107

Can I use environment variables in my CMD stanza in a Dockerfile?

I want to do something like this:

CMD ["myserver", "--arg=$ARG", "--memcache=$MEMCACHE_11211_TCP_ADDR:$MEMCACHE_11211_TCP_PORT"]

Where $MEMCACHE_11211_TCP_* would be set automatically by the inclusion of the --link parameter of my docker run command. And $ARG would be configurable by the user at runtime, maybe by the "-e" parameter?

This doesn't seem to be working for me, it seems to be literally passing through the string "$ARG" for example.

brooks94
  • 3,836
  • 4
  • 30
  • 57

4 Answers4

78

This answer may be a little late. But environment for CMD is interpreted slightly differently depending on how you write the arguments. If you pass the CMD as a string (not inside an array), it gets launched as a shell instead of exec. See https://docs.docker.com/engine/reference/builder/#cmd.

You may try the CMD without the array syntax to run as a shell:

CMD myserver --arg=$ARG --memcache=$MEMCACHE_11211_TCP_ADDR:$MEMCACHE_11211_TCP_PORT
Wes Lord
  • 463
  • 5
  • 11
Andy Shinn
  • 26,561
  • 8
  • 75
  • 93
  • 3
    If you use the `CMD string` approach though, it's possible that `Ctrl-C` will stop working when you use `docker run my-image` because the shell gets the interrupt instead of the process being started by `CMD`. – beporter Jul 19 '21 at 22:13
44
CMD ["sh", "-c", "echo ${MY_HOME}"]

Answer from sffits here.

halfer
  • 19,824
  • 17
  • 99
  • 186
Alex Punnen
  • 5,287
  • 3
  • 59
  • 71
  • 1
    my problem with this is that I am trying to add ssl parameters to postgres command which is already defined in the alpine base dockerfile. My cmd looks like this CMD [ "-c", "ssl=on" , "-c", "ssl_cert_file=/var/lib/postgresql/postgresdb.crt", "-c", "ssl_key_file=/var/lib/postgresql/postgresdb.key", "-c", "ssl_ca_file=/var/lib/postgresql/myCA.crt", "-c", "ssl_crl_file=/var/lib/postgresql/myCA.crl" ] how will you put a variable in this? – PirateApp Aug 26 '22 at 14:51
13

Both Andys had it right. The json syntax bypasses the entrypoint. When you use CMD as in their example, it is considered as an argument to the default entrypoint: /bin/sh -c which will interpret the environement variables.

Docker does not evaluate the variables in CMD in either case. In the former, the command is directly called so nothing gets interpreted, in the later, the variables are interpreted by sh.

creack
  • 116,210
  • 12
  • 97
  • 73
8

I can't speak to how it is supposed to work, but I think if you called this as a shell script, e.g. CMD runmyserver.sh, then the interpretation of the shell variables would be deferred until the CMD actually ran.

So, try

myserver --arg=$ARG --memcache=$MEMCACHE_11211_TCP_ADDR:$MEMCACHE_11211_TCP_PORT`` 

as a shell script?

Andy
  • 35,844
  • 6
  • 43
  • 50