How to use CMD and ENTRYPOINT effectively in your Dockerfiles for running containers.
The Docker instructions,
ENTRYPOINT, are used in Dockerfiles and Docker Compose files to configure the commands used to run a container. This tutorial will explain the differences between them and how to best use them in your Dockerfiles.
Entrypoint sets the command and parameters that will be executed first when a container is run.
Any command line arguments passed to
docker run <image> will be appended to the entrypoint command, and will override all elements specified using
CMD. For example,
docker run <image> bash will add the command argument
bash to the end of the entrypoint.
Dockerfiles use all uppercase letters for the entrypoint instruction. There are several ways you can define this.
The exec syntax
The exec form is where you specify commands and arguments as a JSON array. This means you need to use double quotes rather than single quotes.
ENTRYPOINT ["executable", "param1", "param2"]
Using this syntax, Docker will not use a command shell, which means that normal shell processing does not happen.If you need shell processing features, then you can start the JSON array with the shell command.
ENTRYPOINT [ "sh", "-c", "echo $HOME" ]
Using an entrypoint script
Another option is to use a script to run entrypoint commands for the container. By convention, it often includes entrypoint in the name. In this script, you can setup the app as well as load any configuration and environment variables. Here is an example of how you can run it in a Dockerfile with the
ENTRYPOINT exec syntax.
COPY ./docker-entrypoint.sh / ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["postgres"]
For example, the Postgres Official Image uses the following script as its
#!/bin/bash set -e if [ "$1" = 'postgres' ]; then chown -R postgres "$PGDATA" if [ -z "$(ls -A "$PGDATA")" ]; then gosu postgres initdb fi exec gosu postgres "$@" fi exec "$@"
Docker Compose entrypoint
The instruction that you use in your Docker Compose files is the same, except you use lowercase letters.
You can also define the entrypoint with lists in your
entrypoint: - php - -d - zend_extension=/usr/local/lib/php/xdebug.so - -d - memory_limit=-1 - vendor/bin/phpunit
You can override entrypoint instructions using the
docker run --entrypoint or
docker-compose run --entrypoint flags.
CMD / command
The main purpose of a
CMD (Dockerfiles) /
command (Docker Compose files) is to provide defaults when executing a container. These will be executed after the entrypoint.
For example, if you ran
docker run <image>, then the commands and parameters specified by
command in your Dockerfiles would be executed.
CMD in Dockerfiles
In Dockerfiles, you can define
CMD defaults that include an executable. For
If they omit the executable, you must specify an
ENTRYPOINT instruction as
CMD ["param1","param2"] # (as default parameters to ENTRYPOINT)
NOTE: There can only be one
CMD instruction in a
Dockerfile. If you list
more than one
CMD, then only the last
CMD will take effect.
Docker Compose command
When using Docker Compose, you can define the same instruction in your
docker-compose.yml, but it is written in lowercase as the full word
command: ["bundle", "exec", "thin", "-p", "3000"]
You can override the commands specified by
CMD when you run a container.
docker run rails_app rails console
If the user specifies arguments to
docker run, then they will override the default specified in
Although there are different ways to use these instructions, Docker gives some guidance on best practices for their use and syntax.
Usage best practices
Docker recommends using
ENTRYPOINT to set the image’s main command, and then using
CMD as the default flags. Here is an example Dockerfile that uses both instructions.
FROM ubuntu ENTRYPOINT ["top", "-b"] CMD ["-c"]
Syntax best practices
As well as the exec syntax, Docker allows shell syntax as another valid option for both
CMD. This executes this command as a string and performs variable substitution.
ENTRYPOINT command param1 param2
CMD command param1 param2
However, this tutorial did not emphasise it due the exec syntax being seen as best practice.
CMDshould almost always be used in the form of
CMD [“executable”, “param1”, “param2”…]. Thus, if the image is for a service, such as Apache and Rails, you would run something like
CMD ["apache2","-DFOREGROUND"]. Indeed, this form of the instruction is recommended for any service-based image.
The Dockerfile reference explains more about some of the issues.
ENTRYPOINTshell form prevents any
runcommand line arguments from being used, but has the disadvantage that your
ENTRYPOINTwill be started as a subcommand of
/bin/sh -c, which does not pass signals. This means that the executable will not be the container’s
PID 1- and will not receive Unix signals - so your executable will not receive a
docker stop <container>
CMDis used to provide default arguments for the
ENTRYPOINTinstruction, both the
ENTRYPOINTinstructions should be specified with the JSON array format.
ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe how they interact.
- Dockerfiles should specify at least one of
ENTRYPOINTshould be defined when using the container as an executable.
CMDshould be used as a way of defining default arguments for an
ENTRYPOINTcommand or for executing an ad-hoc command in a container.
CMDwill be overridden when running the container with alternative arguments.
Find out more
The Docker Documentation is a good place to learn more about Dockerfiles and see working examples of ways to use the commands.