If you just need to set an environment variable to a static string, use the Dockerfile ENV
directive.
ENV CONFIG_FILE=/path/to/config.file
CMD ["./main.py"]
The Dockerfile ENTRYPOINT
and CMD
directives (and also RUN
) have two forms. You've used the JSON-array form; in that form, there is not a shell involved and you have to manually split out words. (You are trying to run a command CONFIG_FILE=... ./main.py
, where the executable file itself needs to include the =
and space.) If you don't use the JSON-array form you can use the shell form instead, and this form should work:
CMD CONFIG_FILE=/path/to/config.file ./main.py
In general you should prefer CMD
to ENTRYPOINT
. There's a fairly standard pattern of using ENTRYPOINT
to do first-time setup and then execute the CMD
. For example, if you expected the configuration file to be bind-mounted in, but want to set the variable only if it exists, you could write a shell script:
#!/bin/sh
# entrypoint.sh
#
# If the config file exists, set it as an environment variable.
CONFIG_FILE=/path/to/config.file
if [ -f "$CONFIG_FILE" ]; then
export CONFIG_FILE
else
unset CONFIG_FILE
fi
# Run the main container CMD.
exec "$@"
Then you can specify both the ENTRYPOINT
(which sets up the environment variables) and the CMD
(which says what to actually do)
# ENTRYPOINT must be JSON-array form for this to work
ENTRYPOINT ["./entrypoint.sh"]
# Any valid CMD syntax is fine
CMD ["./main.py"]
You can double-check the environment variable setting by providing an alternate docker run
command
# (Make sure to quote things so the host shell doesn't expand them first)
docker run --rm my-image sh -c 'echo $CONFIG_FILE'
docker run --rm -v "$PWD:/path/to" my-image sh -c 'echo $CONFIG_FILE'
If having the same environment in one-off debugging shells launched by docker exec
is important to you, of these approaches, only Dockerfile ENV
will make the variable visible there. In the other cases the environment variable is only visible in the main container process and its children, but the docker exec
process isn't a child of the main process.