This post is just a small compendium of links and ideas I found somewhere else while I was working on the following problem:
How to pass variables from a docker-compose file into a build stage in the Dockerfile?
The context
It turns out environment variables can be tricky, there are a few different levels and abstractions for each one of them. For example, if docker-compose.yaml
builds a service from a Dockerfile
stage and inside the container we have our own javascript framework with a .env or some defaults, we have the following levels of environment variables:
docker-compose.yaml
Dockerfile
- Container environment files
- NPM script environment variables
- Application defaults
If you are like me, it can get messy after a while.
The flow
First let's get the javascript part out of the way:
- Already existing vars have precedence over .env vars unless you programmatically decide not to.
- NPM script vars take precedence over container environment vars.
Now, the Docker part. According to the docker-compose file documentation, available here:
- env_file add environment variables from a file.
- environment add environment variables... but, in the note at the end of the section it mentions that:
If your service specifies a build option, variables defined in environment are not automatically visible during the build. Use the args sub-option of build to define build-time environment variables.
- args add build arguments, which are environment variables accessible only during the build process.
Well, it is very clear, once you read it. But it is common to assume how things work or to ignore that this document is out there, as you can see from issue #1837.
At this point we know how to pass a variable from the docker-compose.yaml
to the Dockerfile
, but that does not mean that this ARG
will be available inside of the container. To achieve that we need to assign the ARG to ENV as follows:
ARG CONT_IMG_VER
ENV CONT_IMG_VER $CONT_IMG_VER
This time the source is the Dockerfile reference. There is a catch that is discussed after that section, you have to be aware of the cache miss on the first use of the ARG
.
As you can see, it is not that hard to get it right, but you need to be aware of a few conventions that are not as intuitive as it might seem. Hope this save you a few minutes.
Finally, here is an interesting post I found while looking for this, Docker ARG, ENV and .env - a Complete Guide.
Cover image by Yohann Mourre on Unsplash
Top comments (1)
There are several twists on passing values into build time and runtime docker processes. This article is great for anyone tinkering with what's available.
My friends and I did some hybrid things to organize the potential docker chaos by creating this framework... github.com/bah-insignia/zcmd