Reputation: 496
I've found that if I define an environment variable in a docker-compose service entry, that it will not be expanded in other variables defined in the environment section but it will be expanded if the variable is defined in an env file, e.g.
someserver:
image: "some-server:latest"
restart: always
ports:
- "8849:8849"
environment:
javaMemoryLimit: 3056M
JAVA_OPTS: "-Xmx${javaMemoryLimit} -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.port=8849 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.rmi.port=8849 -Djava.rmi.server.hostname=localhost"
When I do a docker-compose up
with this I get warnings about variable not being set:
WARNING: The javaMemoryLimit variable is not set. Defaulting to a blank string.
The same occurs if I use the list form of environment definition.
But if the variable javaMemoryLimit is defined in a .env then the expansion is fine. I've also tried using $$javaMemoryLimit
and then I don't get the warning message but the variable is not expanded when the container actually starts. Any ideas?
Upvotes: 4
Views: 4400
Reputation: 3370
command:
and $$var_name
In the command:
property of a compose file, you actually can expand variables defined in environment:
.
(No idea why this does not seem to be documented anywhere, or whether it will remain true forever? From docker 25.0.2 -- ymmv!)
services:
dumtest:
image: some-basic-image
environment:
- foo_cmd=/bin/ls -ald /etc
command: >
bash -c '
set -ue;
echo Notice how we are expanding "foo_cmd" inline within the command, and
echo this expansion is happening in the container environment, not the
echo parser of the compose file.
echo Be aware that one must be careful not to use a single quote
echo anywhere in this command block! It cannot be escaped.
echo Expand the PATH inside the container:
echo $$PATH;
echo [foo_cmd=$$foo_cmd];
echo Run foo_cmd inside the container:
eval $$foo_cmd
echo Expand the PATH in the compose.yaml parser:
echo $PATH
'
Output from a test run:
$/testdir> docker compose dumtest
Notice how we are expanding foo_cmd inline within the command, and this
expansion is happening in the container environment, not the
parser of the compose file.
Be aware that one must be careful not to use a single quote
anywhere in this command block! It cannot be escaped.
Expand the PATH inside the container:
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
[foo_cmd=/bin/ls -ald /etc]
Run foo_cmd inside the container:
drwxr-xr-x. 1 root root 66 Jan 6 11:54 /etc
Expand the PATH in the compose.yaml parser:
/opt/bb/bin/code-server/lib/vscode/bin/remote-cli:/root/.local/bin:/usr/share/Modules/bin:/opt/bb/lib64/bin:/opt/bb/sbin:/opt/bb/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
Upvotes: 0
Reputation: 596
This is deliberate variable substitution behavior. Only .env
and variables from the shell environment are evaluated at the docker-compose.yaml
level. Otherwise, ${javaMemoryLimit}
will expand to an empty string.
As a side note: even more annoying is the fact that NO variable substitution whatsoever is done in files specified byenv_file:
.
That said, if you do "-Xmx$${javaMemoryLimit} -D...
whatever expands JAVA_OPTS
might work since that should expand to -Xmx${javaMemoryLimit} -D...
(instead of -Xmx -D...
) in your ENTRYPOINT
.
Upvotes: 4