Skip to content

Docker Container Lifecycle: Create to Remove

A container moves through a few states during its life: created, running, paused, exited and finally removed. The introduction showed a short diagram of this. In this lab you'll drive one container through every state, check the state after each command, and learn what each command really does to the process inside.

Every output below is from a real run on Docker Engine 29, using the nginx image from the previous lab.

The states at a glance

                docker start                         docker pause
  docker create ------------>  RUNNING  ------------------------------>  PAUSED
       |                     ^    |    ^ <------------------------------
       v                     |    |    |          docker unpause
    CREATED                  |    |    |
                docker start |    |    | docker restart (stop + start)
                             |    v    |
                            EXITED  ----- docker rm ----->  (removed)
                 (docker stop / docker kill / process ends)

  docker run = docker create + docker start
  docker rm -f = stop (kill) + remove

To watch the state precisely, this lab uses docker inspect with a format string after each step:

docker inspect web-demo --format "status={{.State.Status}} exitCode={{.State.ExitCode}} restarts={{.RestartCount}}"

1. docker create: a container that isn't running

docker create --name web-demo nginx
Output (ID shortened) and state
19262781837c
status=created exitCode=0 restarts=0

docker create prepares everything (the writable layer, the configuration, the name) but doesn't start the process. The container appears in docker ps -a with status Created. This is useful when you want to configure or copy files into a container before it runs. Most of the time you'll use docker run, which is create and start in one step.

2. docker start: running

docker start web-demo
Output, then state and docker ps
web-demo
status=running exitCode=0 restarts=0
web-demo  Up Less than a second

Docker starts the image's command (here Nginx) as the container's main process, which gets PID 1 inside the container.

3. docker pause and unpause: frozen, not stopped

docker pause web-demo
Output, then state and docker ps
web-demo
status=paused exitCode=0 restarts=0
web-demo  Up 1 second (Paused)
docker unpause web-demo
Output, then state and docker ps
web-demo
status=running exitCode=0 restarts=0

pause freezes every process in the container using the cgroup freezer. The processes keep their memory but get no CPU time, so a paused web server doesn't answer requests. unpause continues exactly where they were. It's rarely used day to day, but it's a common interview question.

4. docker stop: graceful shutdown

docker stop web-demo
Output, then state and docker ps
web-demo
status=exited exitCode=0 restarts=0
web-demo  Exited (0) Less than a second ago

docker stop sends the main process a SIGTERM signal ("please shut down"). Nginx finishes its work and exits cleanly, which took about half a second here, with exit code 0. If the process ignores SIGTERM, Docker waits (10 seconds by default; change it with -t) and then sends SIGKILL.

The stopped container keeps its name, settings and writable layer. Nothing is lost until you remove it.

5. docker restart

docker start web-demo
docker restart web-demo
Output, then state and docker ps
web-demo
status=running exitCode=0 restarts=0
web-demo  Up Less than a second

docker restart is a stop followed by a start. Use it after changing a configuration file inside the container or when an app needs a fresh start. Note that restarts is still 0: that counter only counts restarts done automatically by a restart policy (see below), not manual ones.

6. docker kill: immediate stop

docker kill web-demo
Output, then state and docker ps
web-demo
status=exited exitCode=137 restarts=0
web-demo  Exited (137) Less than a second ago

docker kill sends SIGKILL straight away. The process gets no chance to clean up (close connections, flush files). The exit code is 137 = 128 + 9, where 9 is the number of SIGKILL. When you see Exited (137) in real life, the container was killed: by docker kill, by a stop timeout, or by the system because it ran out of memory.

7. docker rm: remove

You can't remove a running container with a plain docker rm:

docker start web-demo
docker rm web-demo
Output
Error response from daemon: cannot remove container "web-demo": container is running: stop the container before removing or force remove

Either stop it first, or force it with -f, which kills and removes in one step:

docker rm -f web-demo
Output
web-demo

docker ps -a --filter name=web-demo now returns nothing: the container is gone.

Removing deletes the container's writable layer. Anything that was written inside the container (and not to a volume) is gone. The image is not affected; you can create a new container from it at any time.

Exit codes tell you why a container stopped

docker run --name fail-demo alpine sh -c "echo working...; exit 3"
docker ps -a --filter name=fail-demo
Output
working...
fail-demo  Exited (3) Less than a second ago
Exit codeUsual meaning
0The process finished normally (or stopped gracefully with docker stop)
1, 2, 3...The application reported an error. Check docker logs
125The docker run command itself failed (bad option, for example)
126 / 127The command couldn't be executed / wasn't found in the image
137Killed with SIGKILL (docker kill, stop timeout or out of memory)
143Ended by SIGTERM (128 + 15) without handling it

Restart policies: let Docker restart containers

A restart policy tells the daemon what to do when the main process exits. Here an alpine container prints a line, waits two seconds and fails with exit code 1:

docker run -d --name always-demo --restart unless-stopped alpine sh -c "echo started; sleep 2; exit 1"

Nine seconds later:

Output
restart policy=unless-stopped restarts=3 status=running

Docker restarted it three times by itself (with a growing delay between attempts). The available policies:

PolicyBehaviour
no (default)Never restart automatically
on-failure[:N]Restart only when the exit code isn't 0, optionally at most N times
alwaysAlways restart, and start again when the daemon starts, even after a manual stop
unless-stoppedLike always, but a container you stopped manually stays stopped after a daemon restart

For a small server running a few containers, --restart unless-stopped is a common choice. In Kubernetes, the platform handles restarts instead.

Lifecycle command cheat sheet

CommandFrom stateTo state
docker create(none)created
docker run(none)running
docker startcreated / exitedrunning
docker pause / unpauserunning / pausedpaused / running
docker stoprunningexited (SIGTERM, then SIGKILL after timeout)
docker killrunningexited (SIGKILL, code 137)
docker restartrunning / exitedrunning
docker rmcreated / exitedremoved
docker rm -fanyremoved

Interview questions

What is the difference between docker stop and docker kill?

docker stop sends SIGTERM and lets the application shut down gracefully, sending SIGKILL only after a timeout (10 seconds by default). docker kill sends SIGKILL immediately, so the process can't clean up; the exit code is 137.

What is the difference between docker stop and docker rm?

docker stop ends the process but keeps the container, so it can be started again with its data and settings. docker rm deletes the stopped container and its writable layer permanently.

What does exit code 137 mean?

The process was killed with SIGKILL (128 + 9): by docker kill, by docker stop after the timeout, or by the kernel's out-of-memory killer.

What is the difference between pause and stop?

Pause freezes the processes in memory without ending them; unpause continues them. Stop terminates the processes; start runs the command again from the beginning.

Summary

  • Container states: created, running, paused, exited, removed.
  • stop is graceful (SIGTERM), kill is immediate (SIGKILL, exit 137).
  • A stopped container keeps its data and settings; rm deletes them, but never the image.
  • Exit codes and restart policies tell you, and Docker, what to do when a container stops.

Next lab: Docker logs and exec: read a container's output and work inside a running Nginx container.