I am working on a simple Docker image that has a large number of environment variables. Are you able to import an environment variable file like with docker-compose? I cannot find anything about this in the docker file documentation.
Dockerfile
FROM python:3.6
ENV ENV1 9.3
ENV ENV2 9.3.4
...
ADD . /
RUN pip install -r requirements.txt
CMD [ "python", "./manager.py" ]
I guess a good way to rephrase the question would be: how do you efficiently load multiple environment variables in a Dockerfile? If you are not able to load a file, you would not be able to commit a docker file to GitHub.
Use -e or --env value to set environment variables (default []). If you want to use multiple environments from the command line then before every environment variable use the -e flag. Note: Make sure put the container name after the environment variable, not before that.
Dockerfile provides a dedicated variable type ENV to create an environment variable. We can access ENV values during the build, as well as once the container runs.
ENV is for future running containers. ARG for building your Docker image. ¶ ENV is mainly meant to provide default values for your future environment variables.
We can run a command to launch a docker container, docker run as arguments by adding an -e flag, or a shorthand for –env to pass the environment variable For example, we can run the following command to pass variables to a container.
Environment Variables in Dockerfile vs. Container Dockerfile is a script containing instructions on how to build a Docker image. On the other hand, a Docker container is a runnable instance of an image. Depending on our needs, we may need to have build-time or run-time environment variables.
In docker, if we do not set an environment variable, it will not have any value and docker compose substitutes them with an empty string. When working in docker, sometimes we might need to pass environment information to the operating container. To achieve this, we can employ both ENV and ARG variables.
Dockerfile provides a dedicated variable type ENV to create an environment variable. We can access ENV values during the build, as well as once the container runs. Let's see how we can use it to pass value to our greetings script.
Yes, there are a couple of ways you can do this.
In Docker Compose, you can supply environment variables in the file itself, or point to an external env file:
# docker-compose.yml
version: '2'
services:
service-name:
image: service-app
environment:
- GREETING=hello
env_file:
- .env
Incidentally, one nice feature that is somewhat related is that you can use multiple Compose files, with each subsequent one adding to the other. So if the above were to define a base, you can then do this (e.g. per run-time environment):
# docker-compose-dev.yml
version: '2'
services:
service-name:
environment:
- GREETING=goodbye
You can then run it thus:
docker-compose -f docker-compose.yml -f docker-compose-dev.yml up
To do this in Docker only, use your entrypoint or command to run an intermediate script, thus:
#Dockerfile
....
ENTRYPOINT ["sh", "bin/start.sh"]
And then in your start script:
#!/bin/sh
source .env
python /manager.py
I've used this related answer as a helpful reference for myself in the past.
To amplify my remark in the comments, if you make your entry point a shell or Python script, it is likely that Unix signals (stop, kill, etc) will not be passed onto your process. This is because that script will become process ID 1, which makes it the parent process of all other processes in the container - in Linux/Unix there is an expectation that this PID will forward signals to its children, but unless you explicitly implement that, it won't happen.
To rectify this, you can install an init system. I use dumb-init from Yelp. This repo also features plenty of detail if you want to understand it a bit better, or simple install instructions if you just want to "install and forget".
There are various options:
https://docs.docker.com/engine/reference/commandline/run/#set-environment-variables--e-env-env-file
docker run -e MYVAR1 --env MYVAR2=foo --env-file ./env.list ubuntu bash
(You can also just reference previously exported
variables, see USER
below.)
The one answering your question about an .env file is:
cat env.list
# This is a comment
VAR1=value1
VAR2=value2
USER
docker run --env-file env.list ubuntu env | grep VAR
VAR1=value1
VAR2=value2
docker run --env-file env.list ubuntu env | grep USER
USER=denis
You can also load the environment variables from a file. This file should use the syntax variable=value
(which sets the variable to the given value) or variable
(which takes the value from the local environment), and # for comments.
Regarding the difference between variables needed at (image) build time or (container) runtime and how to combine ENV
and ARG
for dynamic build arguments you might try this:
ARG or ENV, which one to use in this case?
I really like @halfers approach, but this could also work. docker run
takes an optional parameter called --env-file
which is super helpful.
So your docker file could look like this.
COPY .env .env
and then in a build script use:
docker build -t my_docker_image . && docker run --env-file .env my_docker_image
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With