Docker container with entrypoint variable expansion and CMD parameters
Asked Answered
C

2

20

I want to create a Docker Image that acts as an executable for which the user passes a token as an environment variable. The executable has sub commands that the user should pass via dockers CMD (think of git with authentication via Env). However, Docker does not append the CMD to the entrypoint. The relevant part of my Dockerfile looks like this:

ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/mycmd --token=$MY_TOKEN"]
CMD ["pull", "stuff"]

So if this container is executed without any CMD overrides and secret as the MY_TOKEN variable, I would expect

mycmd --token=secret pull stuff

to be executed. If the user starts the container with an override, e.g.

docker run -it -e MY_TOKEN=secret myimage push junk

I would expect

mycmd --token=secret push junk

to be executed. As mentioned above, however, only mycmd --token=secret gets executed, the CMD is ignored - no matter if I override it during start or set it in the Dockerfile.

Chain answered 17/2, 2017 at 12:37 Comment(5)
did you try docker run -it -e MY_TOKEN=secret myimage "push junk"?Floranceflore
yes, that doesn't work either. That would also not explain why it doesn't work without overriding CMD in docker runChain
try to change your CMD in the Dockerfile with CMD ["sh", "-c", "pull", "stuff"], recreate an image and retestFloranceflore
try moving the whole entrypoint into another shell script. Perhaps CMD is being passed to /bin/sh rather than /usr/bin/mycmd. ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]Rabbitfish
Have you considered this: blog.docker.com/2017/02/docker-secrets-managementRip
C
21

With /bin/sh -c "script" syntax, anything after the -c argument becomes an argument to your script. You can reach them with $0 and $@ as part of your /bin/sh script:

ENTRYPOINT ["/bin/sh", "-c", "exec /usr/bin/mycmd --token=$MY_TOKEN $0 $@"]
CMD ["pull", "stuff"]

Note that you could also change your entrypoint to be a shell script added to your image that runs exec /usr/bin/mycmd --token=$MY_TOKEN "$@" and execute that shell script with docker's exec syntax:

ENTRYPOINT ["/entrypoint.sh"]
Caviness answered 19/2, 2017 at 20:53 Comment(2)
I've updated my commands to use "exec" before /usr/bin/mycmd to remove the extra shell script running as pid 1.Caviness
+1 for using /entrypoint.sh and the exec. Just one thing to note: You should quote the $@, e.g.: exec /usr/bin/mycmd --token=$MY_TOKEN "$@". Otherwise you may get strange behavior when spaces are encountered in the arguments.Zerla
L
6

As specified in the docker documentation, you are specifying an entrypoint that calls a shell (thus not in the shell form, but the exec one). The parameters are passed to the shell (and therefore ignored); only the command in the shell matters. You will see your issue solved after switching your entrypoint call to:

ENTRYPOINT ["usr/bin/mycmd", "--token=$MY_TOKEN"]

Calling a shell in an entrypoint is something heavily discouraged, and precisely only useful when you want to avoid users of the image append custom parameters to your entrypoint.

See you in the interwebs! :)

Lunitidal answered 17/2, 2017 at 14:32 Comment(5)
This does not work, because in the exec form, no environment variabels are expanded: docker: Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "exec: \"/usr/bin/mycmd --token=$MY_TOKEN\": stat /usr/bin/mycmd --token=$MY_TOKEN: no such file or directory".Chain
The correct way would be: ENTRYPOINT ["usr/bin/mycmd", "--token=$MY_TOKEN"]Parchment
this is the same line as in David's answer. Again, this does not expand the environment variable, since it utilizes the exec form.Chain
Sorry, I misread. This actually achieves the correct subcommand substitution. However, the problem with the missing environment variable expansion remains.Chain
I'm not sure if the problem is really missing env substitution. The way it is specified in the answer makes docker try to locate the string "usr/bin/mycmd --token=$MY_TOKEN" as a binary and thus complains with "no such file or directory". The comment made by Ricardo shows the correct syntax.Zerla

© 2022 - 2024 — McMap. All rights reserved.