A known best practice when creating Docker images is when you need to run commands in runtime before starting the actual application/ daemon is to create an entrypoint script and pass the command as parameters in the CMD
instruction. Another best practice is to exec the final command so it would be PID 1 and receive the signals passed to it. Let's create a small example. Here's the Dockerfile
:
FROM alpine COPY entrypoint.sh /entrypoint.sh RUN chmod +x entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] ENV var value CMD ["echo", "$var"]
And the entrypoint.sh
script:
#!/bin/sh set -eu # Perform any needed tasks here. exec $@
Now let's build and run this container:
$ docker build --tag entrypoint . Sending build context to Docker daemon 28.67 kB Step 0 : FROM alpine ---> 5f05d2ba9e65 Step 1 : COPY entrypoint.sh /entrypoint.sh ---> f59f4d7f3546 Removing intermediate container 27ca546c6b6c Step 2 : ENTRYPOINT /entrypoint.sh ---> Running in 98c65b63948a ---> 1de45b33021b Removing intermediate container 98c65b63948a Step 3 : ENV var value ---> Running in 133a8781f0ac ---> bba451334fb2 Removing intermediate container 133a8781f0ac Step 4 : CMD echo $var ---> Running in e8436c6c3202 ---> a49d9b335b74 Removing intermediate container e8436c6c3202 Successfully built a49d9b335b74 $ docker run entrypoint $var
As we can see the variable var
wasn't expanded to it's content. After a bit of head scratching, The following simple change was made to the entrypoint script.
#!/bin/sh set -eu # Perform any needed tasks here. eval "exec $@"
The change is to first evaluate the expression (expanding any variable and expression found), then exec
it. The outcome is what you'd expect.
$ docker build --tag entrypoint . Sending build context to Docker daemon 28.67 kB Step 0 : FROM alpine ---> 5f05d2ba9e65 Step 1 : COPY entrypoint.sh /entrypoint.sh ---> b874d862999d Removing intermediate container fb6483ff00e3 Step 2 : ENTRYPOINT /entrypoint.sh ---> Running in 82adf0b2c4c7 ---> 6674f336c5e1 Removing intermediate container 82adf0b2c4c7 Step 3 : ENV var value ---> Running in 599f3f98c11d ---> 980f1e1e1ad5 Removing intermediate container 599f3f98c11d Step 4 : CMD echo $var ---> Running in e29f1948480a ---> e27fd79143f8 Removing intermediate container e29f1948480a Successfully built e27fd79143f8 $ docker run entrypoint value