Key Differences Between CMD and ENTRYPOINT in a Dockerfile
The main differences between CMD and ENTRYPOINT in a Dockerfile are important for us to know how to set up container behavior. CMD is used to give default arguments for the ENTRYPOINT command or to set a command that runs when a container starts. ENTRYPOINT, on the other hand, sets the command that always runs inside the container. This helps us to keep the application running as we want.
In this article, we will look at the details between CMD and ENTRYPOINT in Dockerfiles. We will see what each one does and how they work together. Here are the topics we will cover:
- Key differences between CMD and ENTRYPOINT in a Dockerfile
- What CMD does in a Dockerfile
- What ENTRYPOINT does in a Dockerfile
- How CMD and ENTRYPOINT work together in a Dockerfile
- When to use CMD or ENTRYPOINT in a Dockerfile
- Best ways to use CMD and ENTRYPOINT in a Dockerfile
- Common questions about CMD and ENTRYPOINT
For more information on Docker, we can read about what is Docker and why you should use it or how Docker is different from virtual machines.
Understanding CMD in a Dockerfile
The CMD instruction in a Dockerfile gives default
commands or arguments for a container when it starts. We can use it to
say what command should run inside the container. But users can change
it when they run the container. There are two ways to write
CMD:
Shell form (runs in a shell):
CMD command param1 param2Exec form (better to use, does not use a shell):
CMD ["executable", "param1", "param2"]
Key Properties of CMD
- Overridable: Users can change the
CMDinstruction when they run the container using the command line. - Single Instance: We can only have one
CMDinstruction in a Dockerfile. If we write more, only the last one will work. - Execution Context: It tells what command to run as the default inside the container.
Examples
We can use CMD in a Dockerfile to run a simple web
server like nginx:
FROM nginx:latest
COPY ./html /usr/share/nginx/html
CMD ["nginx", "-g", "daemon off;"]In this case, when the container starts, it will run
nginx in the foreground as its default command.
For a Python app, it looks like this:
FROM python:3.9
COPY app.py /app.py
CMD ["python", "/app.py"]Here, the container will run python /app.py by default
when it starts.
We should remember that if a user gives a command when they run the
container, it will change the CMD instruction.
Understanding ENTRYPOINT in a Dockerfile
In a Dockerfile, ENTRYPOINT tells what command to run
when we start a container. It helps us set up a container to act like an
executable.
Key Features of ENTRYPOINT:
- Fixed Command: Unlike
CMD, we cannot easily changeENTRYPOINTwhen the container runs. This is good for containers that need to run a certain application. - Syntax: There are two ways to write
ENTRYPOINT:Exec form (we recommend this):
ENTRYPOINT ["executable", "param1", "param2"]Shell form:
ENTRYPOINT command param1 param2
- Combining with CMD: We can use
CMDto give default arguments to theENTRYPOINT.
Example Usage:
FROM ubuntu:latest
ENTRYPOINT ["python3", "app.py"]In this example, when the container starts, it runs
python3 app.py. If we want to add more arguments, we can
use CMD:
FROM ubuntu:latest
ENTRYPOINT ["python3", "app.py"]
CMD ["--help"]Now, the container will run python3 app.py --help by
default.
Environment Variables:
ENTRYPOINT can also use environment variables. This lets
us run commands based on the environment.
FROM ubuntu:latest
ENV APP_ENV=production
ENTRYPOINT ["python3", "app.py"]
CMD ["--env", "$APP_ENV"]Best Practices:
- Use exec form for better control of signals and arguments.
- Combine
ENTRYPOINTwithCMDfor more options in passing parameters. - Think about using
ENTRYPOINTfor containers that are services or applications.
For more info about managing containers and best practices in Docker, check out what is Docker and why should you use it.
How CMD and ENTRYPOINT Work Together in a Dockerfile
In a Dockerfile, we can use CMD and
ENTRYPOINT together to decide how a container starts. They
have different roles but can work well together to make flexible
commands for running containers.
Working Mechanism
ENTRYPOINT: This sets the main command that runs when the container starts. It is the main program for the container. We cannot change this command by default unless we set it to be changeable.
CMD: This gives default arguments to the
ENTRYPOINT. If we do not pass any arguments duringdocker run, it uses the values fromCMD. This helps us keep a default command while also allowing some flexibility in how the container behaves.
Example Usage
Here is an example of using CMD and
ENTRYPOINT together in a Dockerfile:
FROM ubuntu:latest
# Set the ENTRYPOINT
ENTRYPOINT ["python3", "-m", "http.server"]
# Set the CMD
CMD ["8000"]In this example, when we run the container, it will execute:
python3 -m http.server 8000If we want to run it on a different port, we can change the
CMD part:
docker run my-python-server 9000This will execute:
python3 -m http.server 9000Behavior of CMD and ENTRYPOINT
- If we define
ENTRYPOINT, Docker uses it as the main command. - The
CMDinstruction gives default arguments to theENTRYPOINT. - When both
CMDandENTRYPOINTare defined, theCMDis extra parameters to the command inENTRYPOINT.
Combining with Shell Form
We can also write ENTRYPOINT in shell form:
ENTRYPOINT python3 -m http.server
CMD 8000This gives the same result. But it changes how the command is understood. In this case, the default command runs through a shell. This allows us to use shell features like variable substitution.
Best Practices
- Use
ENTRYPOINTfor the main command so it runs as we want. - Use
CMDfor arguments that can be changed. This gives us flexibility in how the container runs. - Avoid using both unless we really need to. It can make command running confusing.
For more about Dockerfiles, you can read what is a Dockerfile and how do you create one.
When to Use CMD vs ENTRYPOINT in a Dockerfile
In a Dockerfile, we need to choose between CMD and
ENTRYPOINT. This choice is important for how our container
works. Here are some tips on when to use each one:
Use CMD When:
- We want to set default options for an
ENTRYPOINT. - We want to let users change the default command when they run the container.
- We need a simple command that does not need extra steps.
Example:
FROM ubuntu
CMD ["echo", "Hello, World!"]This command can change if we give a different command when running the container.
Use ENTRYPOINT When:
- We want to make sure a specific command always runs when the container starts.
- We want to give options to the command without changing it.
- We are making a container that should work like a standalone program.
Example:
FROM ubuntu
ENTRYPOINT ["ping"]
CMD ["localhost"]In this case, ping will always run, and we can change
localhost to a different option.
Combined Use:
- We can use both
ENTRYPOINTandCMDtogether to have more options.ENTRYPOINTsets the main command.CMDgives default arguments.
Example:
FROM ubuntu
ENTRYPOINT ["python"]
CMD ["app.py"]Here, python is the main program. app.py is
the default option, and we can replace it if needed.
Summary:
- Use
CMDfor default options and flexibility. - Use
ENTRYPOINTfor commands that must run. - Combine both for strong command setup in our Dockerfile.
Best Practices for Using CMD and ENTRYPOINT in a Dockerfile
When we use CMD and ENTRYPOINT in a
Dockerfile, we should follow some best practices. This helps our
containers work as we want. Here are some tips to think about:
- Use
ENTRYPOINTfor the Main Command:- We should use
ENTRYPOINTto set the main command that runs when the container starts. This makes our container act like a standalone program.
ENTRYPOINT ["python", "app.py"] - We should use
- Use
CMDfor Default Arguments:- We can use
CMDto give default arguments. Users can change these if they want. This allows flexibility without changing theENTRYPOINT.
CMD ["--port", "8080"] - We can use
- Combine
ENTRYPOINTandCMD:- When we combine
ENTRYPOINTandCMD, we can set the main command and also give default options. This gives us both fixed behavior and flexibility.
ENTRYPOINT ["java", "-jar", "app.jar"] CMD ["--server.port=8080"] - When we combine
- Avoid Using Shell Form:
- We should prefer the exec form (JSON array) instead of the shell
form (string) for
CMDandENTRYPOINT. This helps us avoid problems with signals and makes sure our command runs directly.
ENTRYPOINT ["nginx", "-g", "daemon off;"] - We should prefer the exec form (JSON array) instead of the shell
form (string) for
- Keep it Simple:
- We need to keep our
ENTRYPOINTandCMDcommands simple. If a command needs many arguments, maybe we should create a shell script and call that fromENTRYPOINT.
COPY entrypoint.sh /usr/local/bin/ ENTRYPOINT ["entrypoint.sh"] - We need to keep our
- Document Your Dockerfile:
- We should add comments in our Dockerfile to explain what
CMDandENTRYPOINTdo. This helps us and others understand it better.
# Set the main command for the container ENTRYPOINT ["python", "app.py"] - We should add comments in our Dockerfile to explain what
- Use Health Checks:
- We can use health checks to make sure the app is running fine. This helps manage container restarts and updates.
HEALTHCHECK CMD curl --fail http://localhost:8080/ || exit 1 - Test with Different Scenarios:
- We should test our Dockerfile in different situations. This helps us
see how
CMDandENTRYPOINTwork when we change them or use the defaults.
- We should test our Dockerfile in different situations. This helps us
see how
By following these best practices for CMD and
ENTRYPOINT in a Dockerfile, we can make better and easier
to maintain container images. For more information on Docker and how it
works, check out what
is a Docker container and how does it operate.
Frequently Asked Questions
1. What is the main purpose of CMD in a Dockerfile?
The CMD instruction in a Dockerfile tells what command
to run by default when we start a container from the image. It helps us
define the main action for our container. We can change this action by
giving command-line arguments when we run the container. Knowing how to
use CMD well is important for making our Docker work
better.
2. How is ENTRYPOINT different from CMD in a Dockerfile?
ENTRYPOINT in a Dockerfile sets a command that always
runs when the container starts. This makes it great for setting the main
application to run. Unlike CMD, we cannot change
ENTRYPOINT easily. This means the command we set will
always run no matter what command-line arguments we give. This
difference is important when we want our container to behave the same
way every time.
3. Can we use both CMD and ENTRYPOINT in a Dockerfile?
Yes, we can use both CMD and ENTRYPOINT
together in a Dockerfile. This way, ENTRYPOINT sets the
main command and CMD gives default arguments for that
command. This is useful for making containers that can take extra
parameters while still doing the main job.
4. When should we use CMD vs ENTRYPOINT in a Dockerfile?
We should use CMD when we want to give default arguments
that can be easily changed when we run a container. We should choose
ENTRYPOINT when we need to make sure a specific command
always runs, no matter what arguments we provide. Knowing these
differences can help us manage our Docker containers better and improve
our application’s behavior.
5. What are some good practices for using CMD and ENTRYPOINT in a Dockerfile?
When we use CMD and ENTRYPOINT, we should
keep our commands simple and not use complex scripts. It is better to
use the exec form of commands like
["executable", "param1", "param2"]. This helps with
handling signals and arguments better. For more tips on improving our
Dockerfiles, we can check our article on what
is a Dockerfile and how do you create one.