moby: Dockerfile CMD doesn't understand ARG variables
Similar to #5509.
I want to be able to say the following, without relying upon environment variables:
ARG PATH=/var/run/nowhere
CMD cat ${PATH}
I would like the following consequences of CMD
to occur:
docker inspect container | grep -A5 Cmd
would reveal:"Cmd": [ "/bin/bash", "-c", "cat /var/run/nowhere" ]
- No matter what environment variable PATH is present at runtime, it won’t interfere with my intended CMD.
- I can craft indirect variable interpolation:
ARG COMMAND="echo 'Hello, ${USER}'" CMD ${COMMAND}
About this issue
- Original URL
- State: closed
- Created 7 years ago
- Comments: 18 (5 by maintainers)
Commits related to this issue
- # workaround for https://github.com/moby/moby/issues/34772 in applications Dockerfile — committed to lamba92/maadb-project by lamba92 4 years ago
Please check back in a few years. Docker should be developer-friendly by then.
I agree with https://github.com/moby/moby/issues/34772#issuecomment-330384294.
I don’t really understand why
and
should have wildly different interpolation rules when they are both processed within the same engine at build-time. It seems like the
CMD
can be interpolated using exactly the same rules as are applied toRUN
commands, except that the result would be baked into the image’sCMD
orENTRYPOINT
instead of being evaluated immediately. If the value isn’t supposed to be interpolated immediately, it can be escaped in the same way thatRUN
commands are escaped to deal with this very issue.I completely understand that this might simply be something the
moby
team does not want to do because it is difficult or would break backwards compatibility, but it seems like arguing against a preprocessor that clearly already exists and is used with a consistent set of semantics for directives other thanCMD
andENTRYPOINT
is a bit of a red herring?@thaJeztah I greatly appreciate your patience in explaining your point of view. I still feel like either I don’t understand how ARG works, or you’re not understanding my proposal.
Let’s use HTTP_PROXY as an example.
Scenario 1: Dockerfile author wants to set HTTP_PROXY during build time, but does not want that value to be baked into the layer.
gets translated into the following at build time:
and gets translated into the following at run time:
Scenario 2: Dockerfile author wants to set HTTP_PROXY during build time, and wants HTTP_PROXY to also be hard-coded into the layer for run-time:
gets translated into the following at build time:
and gets translated into the following at run time:
Scenario 3: Dockerfile author wants to set HTTP_PROXY during build time, and wants HTTP_PROXY to be overridden by the user during run-time:
gets translated into the following at build time:
and gets translated into the following at run time:
Am I either completely misunderstanding how ARG and ENV work? Am I missing some dramatic edge case here? This seems like a reasonable approach towards removing the need for templating engines.
As an aside: One of my pet peeves with almost every “DevOps” tool out there is that they all claim to make managing some specific digital artifact much easier, while simultaneously needing some other solution to make managing the tool easy. So we now have Docker to make managing a container easy, but need another tool to make managing Docker easier. I feel like it’s a never-ending cycle of implementing one solution to manage another solution, under the guise of saving time and effort.
Disappointed that this issue has been seemingly abandoned.
The world will never know.
Thanks for the response. I put together a more concrete example to understand your point:
So I think I understand that now, the interpolation is actually being performed implicitly by setting the
ARG
values into the shell environment during each specific RUN command.However, the same interpolation happens on the
WORKDIR
command, which has no shell AFAIK:So what mechanism is performing the interpolation in the non-shell
Dockerfile
directives?Using
exec
in the CMD instruction, as suggested from this stackexchange answer, of the Dockerfile without brackets, I am able to benefit from the environment variable and the signals interception: