1

I'm trying to use ENTRYPOINT and CMD such that ENTRYPOINT is the script I am calling and CMD provides the default arguments to the ENTRYPOINT command but will be overridden by any arguments given to docker run.

The part I'm struggling with is how to have environment variable expanded in my default arguments using CMD.

For example. Given this dockerfile built as tag test:

FROM busybox

ENV AVAR=hello
ENTRYPOINT ["/bin/sh", "-c", "exec echo \"$@\""]
CMD ["${AVAR}"]

I am expecting the following results:

docker run -it --rm test
> hello
docker run -it --rm test world
> world

Note: I'm just using echo here as an example. In my actual Dockerfile I'll be calling ./bin/somescript.sh which is a script to launch an application I have no control over and is what I am trying to pass arguments to.

This question is similar but is asking about expanding variables in the ENTRYPOINT, I'm trying to expand variables in CMD.

I've tried many combinations of shell/exec form for both ENTRYPOINT and CMD but I just can't seem to find the magic combination:

FROM busybox

ENV AVAR=hello
ENTRYPOINT ["/bin/sh", "-c", "exec echo \"$@\""]
CMD ${AVAR}

docker run -it --rm test
> -c ${AVAR}

Is what I'm trying to do possible?

Many more failed attempts


This is the closest I can get:

FROM busybox

ENV AVAR=hello
ENV AVAR2=world
ENTRYPOINT ["/bin/sh", "-c", "echo $@", "$@"]
CMD ["${AVAR}", "${AVAR2}"]

This works fine when I pass in an argument to the run command:

docker run -it --rm test world
> world

But it doesn't expand the default arguments when not given a command:

docker run -it --rm test
> ${AVAR} ${AVAR2}
FGreg
  • 14,110
  • 10
  • 68
  • 110

1 Answers1

0

Found the magic. I don't completely follow what's going on here but I'll try to explain it

FROM busybox

ENV AVAR=hello
ENV AVAR2=world
ENTRYPOINT ["/bin/sh", "-c", "echo $(eval echo $@)", "$@"]
CMD ["${AVAR}", "${AVAR2}"]

docker run -it --rm test
> hello world
docker run -it --rm test world
> world

My attempt at explanation (I'm really not sure if this is right):

CMD in exec form is passed as an argument to ENTRYPOINT without shell substitution. I'm taking those values and passing them as positional arguments to /bin/sh -c ... which is why I need the "extra" "$@" at the end of the ENTRYPOINT array.

Within ENTRYPOINT I need to expand $@ and do parameter substitution on the result of the expansion. So in a subshell ($(...)) I call eval to do parameter substitution and then echo the result which ends up just being the contents of CMD but with variables substituted.

If I pass in an argument to docker run it simply takes place of CMD and is evaluated correctly.

FGreg
  • 14,110
  • 10
  • 68
  • 110
  • Thanks for sharing your finding. Unfortunately this can't be really used when the ENTRYPOINT is defined in a dependent image you have no control over. This really looks like a limitation of Docker. – Jen Feb 04 '21 at 22:53