docker-maven-plugin
docker-maven-plugin copied to clipboard
fabric8's docker:build is importing environment variables from the building process
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
andmvn 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.
- Sample project : [email protected]:3vl/fabric8-build-bug.git
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, 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 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?
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>
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.
Also ran into this problem. Took me some time to solve.
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)
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!
Simplest solution: Add <filter>false</filter>
in the pom file, at configuration/images/image/build
for the plugin execution configuration.