Container States
LEVEL 0
The Problem
You run docker ps and see some containers. You run it again later and some are gone. Where did they go? Are they dead? Can you bring them back?
You try to start a container and get an error: “container already exists.” But you don’t see it in docker ps!
The confusion comes from not understanding that containers have states, and docker ps only shows some of them by default.
LEVEL 1
The Concept — The Employee Status Board
The Concept
Imagine a restaurant with an employee status board.
Employees can be:
- Scheduled — On the roster but haven’t clocked in yet (Created)
- Working — Actively serving customers (Running)
- On Break — Still at work but paused (Paused)
- Clocked Out — Shift ended but still employed (Stopped/Exited)
- Terminated — No longer with the company (Removed)
When the manager looks at “Who’s working right now?”, they see only the employees currently on shift. But the others still exist — they’re just not actively working.
Docker containers work the same way.
docker ps shows “running” containers by default — the ones currently on shift.
docker ps -a shows all containers — including those that have clocked out (stopped).
A stopped container still exists. Its writable layer, its configuration, its changes — all still there. It’s just not running. You can start it again, like calling an employee back from break.
LEVEL 2
The Mechanics — Container States Explained
The Mechanics
Created
A container that exists but has never been started. You can create without starting using docker create.
docker create --name mycontainer nginx
# Container exists but isn't running
Running A container that’s actively executing. The main process is alive and working.
docker start mycontainer
# or
docker run nginx # Creates AND starts
Paused A container that’s frozen in place. All processes are suspended (SIGSTOP). Memory state is preserved. Like pressing pause on a video game.
docker pause mycontainer
docker unpause mycontainer
Stopped (Exited) A container whose main process has ended. Could be because:
- The process completed successfully (exit code 0)
- The process crashed (non-zero exit code)
- You ran
docker stop
The container still exists with all its data — it’s just not running.
Removed (Deleted)
A container that no longer exists. Its writable layer is gone. You need docker run to create a new one.
docker rm mycontainer
LEVEL 3
State Transitions
docker create
│
▼
┌─────────────────────────────────────────────┐
│ CREATED │
└─────────────────────────────────────────────┘
│
docker start
│
▼
┌─────────────────────────────────────────────┐
│ RUNNING │◄──────┐
└─────────────────────────────────────────────┘ │
│ │ │
docker pause docker stop │
│ or process docker start
│ exits │
▼ │ │
┌──────────┐ │ │
│ PAUSED │ │ │
└──────────┘ ▼ │
│ ┌─────────────────────────────────────────┤
docker │ STOPPED │
unpause └─────────────────────────────────────────┘
│ │
│ docker rm
└──────► │
▼
┌─────────────────────────────────────────┐
│ REMOVED │
└─────────────────────────────────────────┘
LEVEL 4
Exit Codes and Process Lifecycle
When a container “stops,” it’s because the main process (PID 1) inside it ended.
Exit Code 0: Success. The process did its job and exited normally.
Exit Code 1-125: Error. Something went wrong in the application.
Exit Code 126: Command not executable (permission denied).
Exit Code 127: Command not found.
Exit Code 128+n: Process killed by signal n. For example:
- Exit code 137 = 128 + 9 (SIGKILL) — Often means out of memory
- Exit code 143 = 128 + 15 (SIGTERM) — Normal
docker stop
You can see exit codes with:
docker ps -a --format "{{.Names}} {{.Status}}"