What are the lifecycle states of a container?

5 minbeginnercontainer-lifecyclecontainer-states

Quick Answer

A container moves through: Created (defined but not yet started), Running (actively executing its main process), Paused (process execution suspended via cgroup freezing, but the container still exists and retains its state), Exited (the main process has stopped, cleanly or due to a crash), and eventually Removed (deleted entirely, along with its writable layer, once you run docker rm). Knowing these states, and that docker stop/docker rm are distinct actions, is essential for managing containers correctly instead of accidentally losing data or leaving stale containers behind.

Detailed Answer

The state diagram

docker create  ──▶  Created
                        │
                   docker startRunning ──── docker pause ───▶ Paused
                        │  ◀─── docker unpause ────────┘
                   docker stop / process exits
                        ▼
                    Exited
                        │
                   docker rm
                        ▼
                    (removed entirely)

Created — defined, but not started

docker create --name my-container myapp:1.0
docker ps -a
# STATUS: Created

The container object exists and its configuration is recorded, but its process hasn't started yet. docker create alone doesn't run anything. docker start — or docker run, which combines create and start in one step — actually launches the process.

Running — actively executing

docker start my-container
docker ps
# STATUS: Up 5 seconds

The container's main process is executing. As long as that process keeps running, the container stays in this state.

Paused — suspended, not stopped

docker pause my-container
docker ps
# STATUS: Paused

docker pause uses cgroup freezing to suspend all processes inside the container. They stop executing entirely, using no CPU time, but stay in memory, fully intact, ready to resume instantly via docker unpause. This is different from stopping — a paused container's process state is preserved mid-execution, not terminated. Rarely used in typical production workflows, but useful for briefly freezing a container to take a consistent filesystem snapshot without fully stopping it.

Exited — the process has stopped

docker stop my-container       # sends SIGTERM, waits, then SIGKILL if needed
docker ps -a
# STATUS: Exited (0) 3 seconds ago

The main process has terminated — cleanly (exit code 0, whether from docker stop or the process finishing naturally) or due to a crash (non-zero exit code). Critically, the container still exists in this state. Its filesystem, including its writable layer's contents, configuration, and logs, is still present and inspectable via docker logs or docker cp. It can be restarted with docker start again, picking up right where its writable layer left off.

Removed — gone entirely

docker rm my-container

This is the only truly destructive, final step. It deletes the container object and its writable layer permanently. Any data that lived only in that writable layer, not in a separate volume, is now unrecoverable.

The critical distinction: stop vs. rm

A common point of confusion: docker stop does not delete anything. The container, its configuration, and its writable layer's data all persist — just not running. docker rm is the actual deletion step. Assuming docker stop alone cleans everything up leads to stopped containers accumulating indefinitely, each still consuming disk space for their writable layers. docker container prune is the standard way to clean up accumulated stopped containers in bulk once you're confident none are needed anymore.

Why this matters practically

Know precisely which commands are destructive (rm) versus merely pausing execution (stop or pause) before running cleanup commands against anything that might hold data you still need. Always confirm whether a container's important data lives in its own writable layer (gone on rm) or in a mounted volume (survives rm) before removing it.

Related Resources