Skip to main content
In this lesson we’ll examine how Docker images determine which process runs inside a container and how to control that behavior using CMD and ENTRYPOINT. This is a foundational topic for predictable container behavior—important for application reliability and signal handling—even if it’s not always covered in certification exams.
A presentation slide titled "Commands and Arguments in Docker" with a stylized icon of a monitor displaying code on a dark curved background. The slide includes a small copyright notice for KodeKloud.
What runs inside a container?
  • A container’s lifecycle is tied to its main process: when the main process exits, the container exits.
  • Containers are typically designed to run a single service or job (for example, a web server, database server, or a short-lived batch task), not act as a full interactive OS.
  • Many images declare a default process in their Dockerfile using CMD or ENTRYPOINT. Official images for services (nginx, MySQL, etc.) typically start the service daemon, while base images (like Ubuntu) often default to an interactive shell.
Example: running the plain Ubuntu image without attaching a terminal
Why did it exit? The default process in many Ubuntu images is a shell (e.g., bash). Since bash expects a TTY and Docker does not attach a TTY by default, the shell exits immediately and the container stops. Common Dockerfile snippets
  • Nginx (simplified): CMD specifies the default program to run:
  • MySQL (simplified): often uses an entrypoint script plus CMD for the server:
  • Ubuntu base image example (defaults to a shell):
Because bash expects a TTY, running this image without a terminal attached results in an immediate exit.
A dark teal illustration showing a circular, tech-style icon of stacked terminal windows labeled "Bash program." Above it is a small code-file icon and the caption "NO terminal attached by default."
Override the image default at runtime
  • Appending a command to docker run replaces the image’s CMD (or is appended to ENTRYPOINT, see below).
  • Example:
This runs sleep 5 inside the container, so the container stays up for 5 seconds then exits. Make the change permanent in a derived image If you want a custom image that always runs a particular command by default, set CMD or ENTRYPOINT in a Dockerfile. Two common forms for CMD:
  • Shell form (runs via a shell):
  • Exec (JSON) form (recommended; no shell, executable receives signals directly):
Important: in JSON (exec) form, each element must be its own string. The first element is the executable and the rest are arguments. Do not use a single string like ["sleep 5"] — that will not be parsed as an executable plus args. Build and run a simple Ubuntu-based image that sleeps:
ENTRYPOINT vs CMD — behavior and use cases
  • CMD defines a default command or default arguments; these can be completely overridden by arguments passed to docker run.
  • ENTRYPOINT configures a fixed executable. Arguments provided on the docker run command line are appended to the ENTRYPOINT command.
Use cases and behavior summary (quick reference) Example Dockerfile using ENTRYPOINT + CMD (exec form — recommended):
Example runtime behaviors:
Shell form caveat: If you write ENTRYPOINT sleep (shell form), Docker will invoke a shell to run that command. This changes signal propagation and argument handling. For reliable signal handling (so the executable receives signals like SIGTERM directly) and predictable argument behavior, prefer the exec/JSON form:
  • Preferred:
    • ENTRYPOINT ["executable", "arg1"]
    • CMD ["default", "args"]
  • Avoid:
    • ENTRYPOINT executable arg1 (shell form)
Best practice: specify ENTRYPOINT and CMD in the exec/JSON form (for example, ENTRYPOINT ["sleep"] and CMD ["5"]) so the executable receives signals directly and arguments are handled predictably.
Quick checklist
  • A container runs as long as its main process runs; when that process exits, the container exits.
  • Use CMD to provide defaults that are easy to override at runtime.
  • Use ENTRYPOINT to enforce a fixed executable and accept runtime arguments appended to it.
  • Prefer the exec/JSON form to avoid shell layers and to get correct signal handling.
Links and references

Watch Video