Problem
I’m trying to get the command inside the docker-compose.yml to use the internal environment variables of the container, rather than the ones of the host system. However, docker compose tries to substitute environment variables in the command with the ones of my own shell, outside the container.
E.g. with the following compose-file:
version: "3.9"
services:
service1:
image: alpine
command: "echo $PATH"
network_mode: bridge
The output contains the PATH of my own shell, not the one inside the container (The variable is getting substituted by Docker).
What I’ve tried
Using a double dollar character as described here. This gives me the following behavior:
YAML syntax | Console Output |
---|---|
command: "echo ${PATH}" |
(Still my own shell PATH variable) |
command: "echo $$PATH" |
$PATH |
command: "echo $${PATH}" |
${PATH} |
As noted above I want the console output to read the value of the actual PATH variable in the container (For the alpine container, the output should be /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
)
I’ve also tried command: "printenv"
, which as expected shows the above internal value of the PATH variable, and not the one from my shell.
Update1
I’ve also tried the exec format as proposed in the comments, with the following forms:
command: ["echo", "${PATH}"]
command: ["echo", "$$PATH"]
command: ["echo", "$${PATH}"]
These still give the same results as above.
Additional Context
OS: Ubuntu 22.04
Compose version: v2.12.2
Question
How can I use internal environment variables inside the command, so that the output of my command will give me the value of the internal PATH variable?
2
Answers
You need to create a .env file next to your docker-compose.yaml and place this inside:
export ENV_VAR=TESTTEST
There are several other techniques: https://docs.docker.com/compose/environment-variables/
The Compose documentation on variable substitution notes that
$VARIABLE
references will be replaced with the corresponding host environment variable anywhere in thedocker-compose.yml
file, including incommand:
.Accessing a container environment variable can be slightly trickier, especially since an entrypoint wrapper script can modify the container environment at startup time. You need to arrange two things to happen:
echo $PATH
, including the dollar sign, into the container; andUnlike in a Dockerfile, Compose will not wrap a plain-string
command:
in/bin/sh -c
, so you have to provide this yourself. Either of these forms will work:But especially notice the double
$$
to force a literal$
to be passed into the container.(This construct also assumes the image will run the
command:
as a normal command. Some images are constructed to ignorecommand:
or to force them to be run with a specific interpreter, and you’ll get an obscure error trying to run this.)