I am trying to run a script as my ENTRYPOINT where the location of that script is defined by environment variables and receives an argument. The script runs but the arg is empty ??
I do NOT want to define the script arg as an environment variable since it contains sensitive data.
Is there any way for me to be able to define the script location in my Dockerfile using environment variables AND be able to pass in one or more arguments into my script via CMD or explicitly with docker run … image arg ??
Here’s a series of examples that hopefully describe the problem. Any help appreciated :
First lets set a baseline to be sure that everything works in the simplest case:
A simple Dockerfile:
FROM ubuntu
ENV ENTRYPOINT_TEST_SCRIPTS_HOME=/usr/local/bin/nexus
ENTRYPOINT_TEST_DEFAULT_SCRIPT=hello.sh
ENTRYPOINT_TEST_VOLUME=/scripts
ENV PATH=$ENTRYPOINT_TEST_SCRIPTS_HOME:$PATH
WORKDIR $ENTRYPOINT_TEST_SCRIPTS_HOME
COPY ./scripts ./
RUN chmod -R 777 $ENTRYPOINT_TEST_SCRIPTS_HOME
VOLUME $ENTRYPOINT_TEST_VOLUME
ENTRYPOINT [“/bin/echo”, “Hello”]
CMD [“World”]
Build the image (note: its NOT running a script yet):
$ docker build -t entrypointtest .
Running this container produces the expected output:
$ docker run -it entrypointtest
Hello World
OK, so lets change the Dockerfile to ask it to run a script by changing the ENTRYPOINT and CMD like so:
ENTRYPOINT [“/usr/local/bin/nexus/hello.sh”]
CMD [“Fraser”]
The script file hello.sh looks like this:
#!/bin/bash
echo “Hello $1”
if [ -z “$1” ]; then
echo
echo “You MUST provide arg value to this script”;
echo
else
echo “Hello $1”
fi
rebuild, re-run and everthing works fine also:
$ docker run -it entrypointtest
Hello Fraser
Hello Fraser
I can successfully send a diffferent script arg:
$ docker run -it entrypointtest George
Hello George
Hello George
… and even use a different entrypoint and cmd arg (goodbye.sh is exactly the same as hello.sh except it echos ‘Goodbye’ instead of ‘Hello’)
$ docker run -it --entrypoint /usr/local/bin/nexus/goodbye.sh entrypointtest George
Goodbye George
Goodbye George
If we look at the COMMAND output for the stopped containers we can see what actually ran in each case:
COMMAND
“/usr/local/bin/nexus/hello.sh Fraser”
“/usr/local/bin/nexus/hello.sh George”
“/usr/local/bin/nexus/goodbye.sh George”
However, what a REALLY want to do is provide the location of the script I want to run via a couple of environment variables. So I updated the Dockerfile like this:
ENTRYPOINT [“/bin/bash”, “-c”, “$ENTRYPOINT_TEST_SCRIPTS_HOME/$ENTRYPOINT_TEST_DEFAULT_SCRIPT”]
CMD [“Fraser”]
Note: I am explictly specifying /bin/bash -c otherwise variable expansion wont happen and you’ll end up with this error when you do docker run:
exec: “$ENTRYPOINT_TEST_SCRIPTS_HOME/$ENTRYPOINT_TEST_DEFAULT_SCRIPT”: stat $ENTRYPOINT_TEST_SCRIPTS_HOME/$ENTRYPOINT_TEST_DEFAULT_SCRIPT: no such file or directory
docker: Error response from daemon: Container command not found or does not exist…
I can use the shell style (see below) to remedy this but it still doesn’t change the outcome.
Anyway, … rebuild, re-run … what happens now is the script does get executed, BUT the arg in CMD is not passed to the script ??
$ docker run -it entrypointtest
Hello
You MUST provide arg value to this script
Same outcome if I explicitly provide an arg:
docker run -it entrypointtest George
If we look at the COMMAND for these two invocations they seem ok (they don’t show the resolved env variable values, but we know the script did execute so variable expansion must be working):
COMMAND
“/bin/bash -c $ENTRYPOINT_TEST_SCRIPTS_HOME/$ENTRYPOINT_TEST_DEFAULT_SCRIPT Fraser”
“/bin/bash -c $ENTRYPOINT_TEST_SCRIPTS_HOME/$ENTRYPOINT_TEST_DEFAULT_SCRIPT George”
Obviously if I explicitly provide an --entrypoint and a cmd arg that will work (because the script location is now once again a hard-coded path):
$ docker run -it --entrypoint /usr/local/bin/nexus/hello.sh entrypointtest George
Hello George
Hello George
… but thats not what I want, I want to be able to do something like:
docker run -it -e ENTRYPOINT_TEST_DEFAULT_SCRIPT=myscript.sh entrypointtest foo
Using the shell style for the Dockerfile ENTRYPOINT/CMD yields the same problem (no arg value passed to the script):
ENTRYPOINT $ENTRYPOINT_TEST_SCRIPTS_HOME/$ENTRYPOINT_TEST_DEFAULT_SCRIPT
CMD Fraser
Is there any way for me to be able to define the script location using environment variables AND be able to pass in one or more arguments into my script via CMD or explicitly with docker run … image arg ??
Regards
Fraser