1

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
  • command can have the shell format (what you are using) or exec form (recommended). Maybe that is what going on. Take a look here docs.docker.com/engine/reference/builder/#cmd Commented Nov 16, 2022 at 16:08
  • 1
    @JoaoVitorino Thanks for your comment! I've tried the exec form also, but it gives the same results (See update above). Note that I've edited my example to using the $PATH variable, to make it more clear that I would want to use internal container environment variables. Commented Nov 16, 2022 at 16:47

2 Answers 2

1

The Compose documentation on variable substitution notes that $VARIABLE references will be replaced with the corresponding host environment variable anywhere in the docker-compose.yml file, including in command:.

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:

  1. You need to pass the literal string echo $PATH, including the dollar sign, into the container; and
  2. You need to make sure a shell runs to process that string.

Unlike 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:

command: sh -c 'echo $$PATH'
command:
  - sh
  - -c
  - echo $$PATH

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 ignore command: or to force them to be run with a specific interpreter, and you'll get an obscure error trying to run this.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks David! This indeed seems to be the only way to do this in a compose file currently. I've accepted the answer. I'm a bit disappointed by docker-compose though, that there's not a more simpler way to do this...
0

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/

7 Comments

Thanks for your answer. Using a .env file still causes the variables to be substituted when the compose-file is parsed, rather then when the command is used. As you indicate, this will work for my original example, if I just want to be able to set the value of one of the variables manually, but I'm looking (more in general) at a method to use internal container environment variables inside the command. I've updated my example to use the $PATH variable, to make this more clear.
a method to use internal container environment variables inside the command. I think that is simply not possible. Can you describe your exact use case (in your question) what you want to achieve?
Looking further in the docs it is clearly stated: "Your configuration options can contain environment variables. Compose uses the variable values from the shell environment in which docker-compose is run. ".
thanks for your reply! Indeed nearly all variables used inside a docker-compose file are substituted using the variables in the shell environment. However, there seems to be a workaround to still be able to use internal environment variables, as illustrated in the answer above (stackoverflow.com/a/74465405/7690374). I've accepted that one, since there indeed doesn't seem to be a more straightforward/better looking method to use internal environment variables in the compose file...
True, should have read the docs further 2 lines, where it says: You can use a $$ (double-dollar sign) when your configuration needs a literal dollar sign. This also prevents Compose from interpolating a value, so a $$ allows you to refer to environment variables that you don’t want processed by Compose. :) Still it would be good to know what your use case really is because this is such a niche or I would even say hacky thing so there must be a more standard way to solve your actual problem.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.