Docker
CMD Override
Container Configuration
Docker Run
Command Line

How to override the CMD command in the docker run line

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

CMD in a Dockerfile defines the default command a container will run when it starts. If you want something different for one invocation, you do not need to rebuild the image; you can override that default directly on the docker run command line.

The detail that trips people up is the interaction between CMD and ENTRYPOINT. Overriding CMD is simple, but if the image also defines an ENTRYPOINT, your command may become arguments to that entrypoint rather than replacing the whole process.

Override CMD at Runtime

If an image only defines CMD, anything you place after the image name in docker run replaces it.

Example Dockerfile:

dockerfile
FROM alpine:3.20
CMD ["echo", "hello from default command"]

Run with the default command:

bash
docker run --rm my-image

Override the CMD:

bash
docker run --rm my-image echo "hello from override"

The second invocation ignores the Dockerfile CMD and runs the command you supplied.

Understand the ENTRYPOINT Interaction

If the image defines both ENTRYPOINT and CMD, Docker combines them. In that model:

  • 'ENTRYPOINT defines the executable'
  • 'CMD provides default arguments'

Example:

dockerfile
FROM python:3.12-slim
ENTRYPOINT ["python", "/app/main.py"]
CMD ["--port", "8080"]

Running the image normally executes:

bash
python /app/main.py --port 8080

If you run:

bash
docker run --rm my-image --port 9090

you are overriding the CMD arguments, not the ENTRYPOINT. The result becomes:

bash
python /app/main.py --port 9090

That is often exactly what you want for application images.

Override the Entry Point When Needed

If you need to bypass the image entrypoint entirely, use --entrypoint.

bash
docker run --rm --entrypoint /bin/sh my-image

That starts a shell instead of the configured application. This is useful for debugging, inspecting files, or verifying environment variables inside the image.

You can also combine --entrypoint with extra arguments:

bash
docker run --rm --entrypoint /bin/sh my-image -c "ls -la /app"

Without --entrypoint, the text after the image name might be treated as arguments to the existing entrypoint, which can be confusing if you expected a shell command to run directly.

Shell Form Versus Exec Form

Dockerfiles support both shell form and exec form for CMD, but exec form is usually safer:

dockerfile
CMD ["python", "worker.py"]

instead of:

dockerfile
CMD python worker.py

Exec form avoids an extra shell layer and handles signals more predictably. That matters for containers that need graceful shutdown behavior under orchestration systems.

From the override perspective, both can be replaced at docker run time, but images using exec form are easier to reason about.

A Practical Debugging Pattern

A common use case is replacing the startup command so you can inspect a broken container:

bash
docker run --rm -it --entrypoint /bin/sh my-image

Then inside the container, you can verify files, dependencies, and startup scripts manually. This is often faster than rebuilding the image blindly.

Another common case is changing a default command for a one-off task:

bash
docker run --rm my-image python manage.py migrate

That works only if my-image does not have an entrypoint that interferes. If it does, inspect the Dockerfile first.

Common Pitfalls

  • Forgetting that text after the image name overrides CMD, not necessarily ENTRYPOINT.
  • Assuming your override replaces the entire startup process when the image has an entrypoint.
  • Using shell form in the Dockerfile and then getting confusing quoting behavior.
  • Debugging a container with a nonexistent shell. Minimal images may not include /bin/sh or bash.

Summary

  • Put a command after the image name in docker run to override CMD.
  • If the image has an ENTRYPOINT, your override may become its arguments instead of replacing it.
  • Use --entrypoint when you need to replace the configured executable itself.
  • Prefer exec form in Dockerfiles because it is easier to reason about and handles signals better.
  • Inspect both CMD and ENTRYPOINT before assuming how a container startup command will behave.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.