ENTRYPOINT and CMD ------------------- CMD vs ENTRYPOINT ~~~~~~~~~~~~~~~~~ **CMD**:: CMD ["/bin/ping", "-c", "3", "localhost"] - Easy to override: use for general purpose images **ENTRYPOINT**:: CMD ["/bin/ping", "-c", "3", "localhost"] - Not made to be overridden: use for specific applications **CMD and ENTRYPOINT**:: ENTRYPOINT ["/bin/ping", "-c", "3"] CMD ["localhost"] - CMD is appended to ENTRYPOINT - Specifies the executable with ENTRYPOINT and the arguments with CMD - The CMD arguments can be overridden by the user of your container - Always use the **exec form** when combining both Shell vs. Exec ~~~~~~~~~~~~~~ With the **shell form**, docker will invoke a shell and pass the specified commands to it:: CMD ping localhost This will be executed as ``/bin/sh -c 'ping localhost'`` by docker. Consequences of the shell form: - the process with PID 1 is the shell and not your application - POSIX signals will be sent to the shell and not forwarded to your application - the container needs to provide a shell at ``/bin/sh`` - variable expansion will happen as you would expect With the **exec form**, docker executes your commands directly in the container, without starting a shell:: CMD ["/bin/ping", "localhost"] Consequences of the exec form: - your process is the PID 1, receiving all signals - no shell needed in the container - your command is interpreted as is, and there is **no variable expansion** (since there is no shell) Forward signals ~~~~~~~~~~~~~~~ If using the shell form or a startup script, we can handle signals correctly by using the ``exec gosu`` combo command while starting the application. This is the official ``Dockerfile`` example using this technique:: #!/usr/bin/env bash set -e if [ "$1" = 'custom-app' ]; then # do something exec gosu custom-app "$@" fi exec "$@"