Docker
docker run command
Dockerfile
CMD instruction
pass arguments

Use docker run command to pass arguments to CMD in Dockerfile

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

Passing runtime arguments correctly in Docker depends on how CMD and ENTRYPOINT are defined in your Dockerfile. Many confusing cases come from mixing shell form and exec form commands. Once you separate defaults from runtime overrides, argument passing becomes predictable.

Understand CMD Versus ENTRYPOINT

CMD provides default arguments or a default command. ENTRYPOINT defines the main executable that always runs. The most flexible pattern is to set executable in ENTRYPOINT and default options in CMD.

dockerfile
1FROM python:3.12-slim
2WORKDIR /app
3COPY app.py .
4
5ENTRYPOINT ["python", "app.py"]
6CMD ["--mode", "dev", "--port", "8080"]

Build and run:

bash
docker build -t demo-args .
docker run --rm demo-args

This runs with default CMD arguments.

Override CMD Arguments at Runtime

When ENTRYPOINT is set, extra values passed to docker run replace CMD only.

bash
docker run --rm demo-args --mode prod --port 9000

The executed command becomes python app.py --mode prod --port 9000.

If you define only CMD and no ENTRYPOINT, passing arguments to docker run replaces the whole command, which is often not what beginners expect.

Inspect Effective Runtime Command

To debug argument behavior, inspect image metadata.

bash
docker inspect demo-args --format '{{json .Config.Entrypoint}} {{json .Config.Cmd}}'

You can also override entrypoint explicitly:

bash
docker run --rm --entrypoint python demo-args app.py --mode test

This is useful for one off diagnostics or shell access.

Pattern for Wrapper Scripts

If your container uses a shell script wrapper, make sure it forwards arguments using "$@".

bash
1#!/bin/sh
2set -e
3
4echo "Starting app"
5exec python app.py "$@"

Dockerfile:

dockerfile
1COPY entrypoint.sh /entrypoint.sh
2RUN chmod +x /entrypoint.sh
3ENTRYPOINT ["/entrypoint.sh"]
4CMD ["--mode", "dev"]

Without argument forwarding, runtime overrides appear to be ignored.

Shell Form Versus Exec Form in Detail

Docker supports shell form and exec form for both CMD and ENTRYPOINT. Shell form runs through a shell process, which changes signal handling and quoting behavior. Exec form runs the binary directly and is preferred for most production services.

Shell form example:

dockerfile
CMD python app.py --mode dev

Exec form example:

dockerfile
CMD ["python", "app.py", "--mode", "dev"]

With shell form, argument escaping can differ between environments and stop signals may not reach the actual app process cleanly. Exec form avoids these issues and makes override behavior explicit.

Combining Environment Variables With Runtime Arguments

Use environment variables for stable defaults that may vary by deployment target, and runtime arguments for per run overrides.

dockerfile
ENV APP_MODE=dev
ENTRYPOINT ["python", "app.py"]
CMD ["--port", "8080"]
bash
docker run --rm -e APP_MODE=prod demo-args --port 9000

This separation keeps images reusable across staging and production while preserving clear runtime control.

Common Pitfalls

  • Using shell form CMD with complex quoting and expecting exec style behavior.
  • Defining both command logic and defaults in CMD only, then losing them on runtime override.
  • Forgetting argument forwarding in wrapper scripts.
  • Assuming docker run image arg1 appends when no ENTRYPOINT exists.
  • Overriding entrypoint in production accidentally and bypassing startup checks.

Summary

  • Use ENTRYPOINT for executable and CMD for default arguments.
  • Runtime arguments after image name replace CMD values.
  • Inspect image config when command behavior is unclear.
  • Wrapper scripts must forward arguments with "$@".
  • Prefer exec form instructions for predictable argument handling.
  • Keep container startup interfaces documented with concrete examples so operators know which flags override defaults and which require image rebuild.
  • Test signal handling with stop and restart scenarios to ensure your chosen command form exits cleanly under orchestration platforms.
  • Keep argument names backward compatible when evolving container interfaces so deployment scripts do not break after image updates.
  • Validate runtime overrides in automated smoke tests so entrypoint and default argument contracts remain trustworthy over time.

Course illustration
Course illustration

All Rights Reserved.