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, whether cleanly or due to a crash/error), and eventually Removed (deleted entirely, along with its writable layer, once you explicitly run docker rm). Understanding these states — and that docker stop/docker rm are distinct actions — is essential for correctly managing containers rather than 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 (its configuration is recorded), but its process hasn't been started yet. docker create alone doesn't run anything. docker start (or the combined docker run, which does both create and start in one step) is what 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 (no CPU time at all), but remain in memory, fully intact, ready to resume instantly via docker unpause. This is distinct from stopping — a paused container's process state is preserved exactly as it was, mid-execution, rather than being terminated. Rarely used in typical production workflows, but useful for scenarios like 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 — either cleanly (exit code 0, whether from docker stop or the process finishing its work naturally) or due to a crash/error (a non-zero exit code). Critically, the container still exists in this state. Its filesystem (including its writable layer's contents), configuration, and logs are all still present and inspectable (docker logs, 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 — see the storage topic) is now unrecoverable.

The critical distinction: stop vs. rm

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

Why this matters practically

Knowing precisely which commands are destructive (rm) versus merely pausing execution (stop, pause) is essential 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, as covered in the storage topic) before removing it.

Related Resources