In Docker, both ENTRYPOINT
and CMD
define what process or command the container will execute when it starts, but they serve slightly different purposes and interact in specific ways:
-
ENTRYPOINT
: Defines the primary executable that will run within the container. This is usually the command or script that you always want to execute when the container starts, regardless of any additional parameters. It’s commonly used for setting up the "base command" or script that should run in all cases (e.g., an initialization script, a specific executable, etc.). -
CMD
: Specifies the default arguments to pass to theENTRYPOINT
or, if noENTRYPOINT
is specified, it acts as the command to run.CMD
is often used to define the "default behavior" but can be overridden by providing a command in the Docker run command or Docker Compose.
How ENTRYPOINT
and CMD
Work Together
When both ENTRYPOINT
and CMD
are specified in a Dockerfile:
ENTRYPOINT
specifies the primary command or executable.CMD
provides the arguments or options for theENTRYPOINT
.
For example, given this Dockerfile:
ENTRYPOINT ["./scripts/wait-for-it.sh", "db:5432", "--"]
CMD ["python", "scripts/init_db.py"]
When the container starts, it will effectively run:
./scripts/wait-for-it.sh db:5432 -- python scripts/init_db.py
In this case:
./scripts/wait-for-it.sh db:5432 --
is theENTRYPOINT
.python scripts/init_db.py
is theCMD
argument passed to theENTRYPOINT
.
Benefits of Using Both
- Modularity: You can set up
ENTRYPOINT
as a stable entry script (e.g., a wait-for script or a wrapper) and useCMD
to specify a default command that can be easily overridden. - Flexibility:
CMD
can be overridden by specifying an alternative command when you run the container. For instance, if you rundocker run myimage echo "Hello"
, it will replacepython scripts/init_db.py
withecho "Hello"
while still running through theENTRYPOINT
.
If Only CMD
or ENTRYPOINT
is Present
- Only
CMD
: Docker will execute theCMD
as the container’s command. - Only
ENTRYPOINT
: You’d need to provide arguments explicitly when running the container if you want to specify them, as there’s no default argument.
Common Use Cases
- Using
ENTRYPOINT
for Initialization Logic: It’s common to set upENTRYPOINT
with initialization tasks, like waiting for a service to be ready (wait-for-it.sh
), and useCMD
for the main application command. - Overriding Commands: With this setup, you can run the container with different commands without modifying the
ENTRYPOINT
logic. For example:docker run myimage python scripts/some_other_script.py
In Your Case
In your setup:
ENTRYPOINT ["./scripts/wait-for-it.sh", "db:5432", "--"]
CMD ["python", "scripts/init_db.py"]
ENTRYPOINT
will run thewait-for-it.sh
script, ensuring that thedb
service is available before starting.CMD
runsinit_db.py
, the database initialization script, by default.
If you wanted to run a different command (e.g., echo "Testing"
), you could override CMD
like this:
docker-compose run db-init echo "Testing"
In this case, wait-for-it.sh
will still execute, but it will run echo "Testing"
instead of python scripts/init_db.py
.
Summary Table
Type | Purpose | Can be Overridden? |
---|---|---|
ENTRYPOINT |
Defines the base command/executable. Typically stable. | No (unless you use --entrypoint ) |
CMD |
Defines default arguments or command if no ENTRYPOINT is set. |
Yes, by providing a new command |
In short:
ENTRYPOINT
is for the fixed part of the command, especially useful for setup tasks.CMD
is for the flexible, default part of the command that can be overridden when needed.