I’m using ENTRYPOINT
to pass in an argument when running docker run
but I cannot get the runtime argument to surface in my script as an argument.
Dockerfile
FROM debian:latest
ENV a="my arg in Dockerfile"
COPY . .
RUN chmod +x myscript.sh
ENTRYPOINT ["/bin/bash", "-c", "/myscript.sh ${a}"]
with myscript.sh
#!/bin/bash
echo "From script: $@"
When I run docker build -t my_image .
then docker run -it --rm my_image
I get the result as expected: From script: my arg in Dockerfile
But when I run docker run -it --rm my_image from_run
I get the same result: From script: my arg in Dockerfile
so the "from_run" is not being passed down to the script through ENTRYPOINT
.
I read that arguments passed after the image name is appended to the ENTRYPOINT
but clearly I’m not understanding something here.
Same result when using the exec form as opposed to JSON form:
ENTRYPOINT /myscript.sh ${a}
https://docs.docker.com/engine/reference/run/#entrypoint-default-command-to-execute-at-runtime
2
Answers
Bash is Bash, see bash manual how
-c
pases arguments. The following:passes only one argument to myscript.sh and that is unquoted
$a
, so$a
undergoes word splitting and filename expansion. And the argumentfrom_run
is assigned to$0
. I would do:Note that it’s typical to use upper case (and unique names) for environment variables
$a
.The main container command is made up of two parts. The string you pass after the
docker run image-name
replaces the DockerfileCMD
, and it’s appended to the DockerfileENTRYPOINT
.For your
docker run
command to work, you need to provide the command you want to run asENTRYPOINT
and its arguments asCMD
. You do not need an environment variable here. However, it is important that both parts use JSON-array syntax and that neither invokes a shell. IfENTRYPOINT
includes a shell then things get syntactically complex (see @KamilCuk’s answer); ifCMD
includes a shell then it won’t get invoked but the command will be invoked with/bin/sh
and-c
as parameters instead.If you want the initial set of command-line arguments to be included and the
docker run
arguments to be appended, you can move them into theENTRYPOINT
line; note that thedocker run --entrypoint
is syntactically awkward if you ever do decide you need to remove some of the options.If you can update your application to accept options as environment variables in addition to command-line settings, this makes all of this syntactically easier.