docker-maven-plugin icon indicating copy to clipboard operation
docker-maven-plugin copied to clipboard

fabric8's docker:build is importing environment variables from the building process

Open 3vl opened this issue 4 years ago • 8 comments

Description

When I build a docker image using docker:build it pulls any environment variable from the maven process that is also defined in the Dockerfile as an ENV entry. When using docker build this only happens if we use the --env parameter.

Info

  • d-m-p version :
  • Maven version (mvn -v) :
Apache Maven 3.6.3 (cecedd343002696d0abb50b32b541b8a6ba2883f)
Maven home: /usr/local/Cellar/maven/3.6.3_1/libexec
Java version: 15.0.1, vendor: N/A, runtime: /usr/local/Cellar/openjdk/15.0.1/libexec/openjdk.jdk/Contents/Home
Default locale: en_US, platform encoding: UTF-8
OS name: "mac os x", version: "10.15.7", arch: "x86_64", family: "mac"
  • Docker version : Docker version 20.10.2, build 2291f6
  • If it's a bug, how to reproduce : (also in README.md of linked repo) There is a difference in how docker build and mvn docker:build handle environment variables. fabric8 seems to pull any environment variable from the mvn process that also has a ENV entry in the Dockerfile and imports it into the docker image.

The demo Dockerfile simply has an ENV INFO=default

To see how docker build handles the situation. Notice that the docker run prints the value default which was set in the Dockerfile and does not the value cows from the docker build process.

$ INFO=cows docker build -t env .
Sending build context to Docker daemon  51.71kB
Step 1/3 : FROM bash
 ---> a3cae8598d52
Step 2/3 : ENV INFO=default
 ---> Using cache
 ---> ed13f219d3c6
Step 3/3 : CMD echo ${INFO}
 ---> Using cache
 ---> 1749f7a40bf0
Successfully built 1749f7a40bf0
Successfully tagged env:latest

$ docker run -it --rm env
default

However, if we build the same image with with fabric8 docker:build notice that the environment variable INFO now has the value of cows which appears to have been picked up from the environment of the maven process.

$ INFO=cows mvn docker:build
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------< test:env >------------------------------
[INFO] Building env 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- docker-maven-plugin:0.34.1:build (default-cli) @ env ---
[INFO] Building tar: /Users/m_884025/dev/fabric8-build-bug/target/docker/env/tmp/docker-build.tar
[INFO] DOCKER> [env:latest]: Created docker-build.tar in 35 milliseconds
[INFO] DOCKER> [env:latest]: Built image sha256:311ca
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  1.521 s
[INFO] Finished at: 2021-02-04T13:55:06-05:00
[INFO] ------------------------------------------------------------------------
$ docker run -it --rm env
cows

fabric8's docker:build seems to be behaving as thought theres an --env parameter for every environment variable in the building process.

3vl avatar Feb 04 '21 19:02 3vl

The issue is, that dmp allows interpolating Maven properties in a Dockerfile. By default, the same delimiter as for Dockerfile ENV variables is used, so that the Dockerfile can be used also outside the context of dmp (whether this was a good choice might be debatable). The interpolation process also uses the build environment as a fallback so that the env variables are resolved, too, during the build. This should be fixed as this leads to more issues then it helps (and also, it is always possible to map an Env to a Maven property, too.

In the meantime, you can disable this behaviour by adding a <filter>@</filter> to the <build> configuration of an <image> so that the interpolation syntax for interpolation Maven properties in a Dockerfile then becomes @mymavenprop@. Or to switch off interpolation completely use <filter>false</false>. See subsection "Filtering" in http://dmp.fabric8.io/#docker:build (the documentation is not fully accurate as it omits that env vars are also used for interpolation)

rhuss avatar Mar 07 '21 21:03 rhuss

@rhuss, thank you for your reply and the explanation. I've been using the "Simple Dockerfile build" method described in section 5.1 of the documentation and I don't see any way to specify or disable this filtering without defining an in the . The docker.filter property seems to be overloaded with the list of images to build selection feature (described in section 3) and the property replacement feature described in section 6. Am I missing something, is there a way to set the property replacement filter and still use the "Simple Dockerfile build" method?

3vl avatar Mar 08 '21 15:03 3vl

Wait, I think I figured it out using external and mode override.

    <configuration>
        <images>
            <image>
                <external>
                    <type>properties</type>
                    <prefix>docker</prefix>
                    <mode>override</mode>
                </external>
                <build>
                    <dockerFileDir>${project.basedir}</dockerFileDir>
                    <filter>@</filter>
                </build>
            </image>
        </images>
    </configuration>

3vl avatar Mar 08 '21 15:03 3vl

Just ran into this. And took a while to figure out what's going on, as the docs don't mention this "feature" and it is violating the principle of least surprise. docker build command doesn't include env vars by default, so it is really unexpected that dmp does. What's worse it overrides the vars defined in the Dockerfile itself.

NersesAM avatar Apr 25 '22 09:04 NersesAM

Also ran into this problem. Took me some time to solve.

csmuc avatar Feb 10 '23 08:02 csmuc

This should be fixed as this leads to more issues then it helps (and also, it is always possible to map an Env to a Maven property, too.

Agreed that the behavior could be better (see my explanation above), but I have zero time to work on this. Happy to help to integrate if somebody is fancy to providing a PR (there should be also a switch to allow the old behavior for some time, for backward compatibility)

rhuss avatar Feb 14 '23 09:02 rhuss

ENV PATH="/foo/bar/bin:${PATH}" This completely messes up the PATH environment variable in the image.

If you use this method to change an existing environment variable, check out the result using docker inspect to confirm.

You may not notice this if you mvn docker:build using a similar OS as the base image, but it completely messed up the PATH when I tried to build a Unix-based image on Windows (WSL) machine.

Please fix this!

johnkeeney avatar Mar 24 '23 19:03 johnkeeney

Simplest solution: Add <filter>false</filter> in the pom file, at configuration/images/image/build for the plugin execution configuration.

johnkeeney avatar Mar 27 '23 13:03 johnkeeney