Running Containers: create, run, start, stop, restart, rm, exec, attach, inspect, and Lifecycle State: Concepts, Architecture, and Mental Model
A container is not simply “running” or “not running.” Docker persists a container object with configuration and identity, while its primary process can move through created, running, stopped/exited, restarting, paused, or dead states. This lesson builds that state machine before adding operational commands.
Learning objectives
- Distinguish the persistent Docker container object from the primary process currently executing inside it.
- Explain the transition from image plus container configuration to created object, running process, stopped/exited object, restart, and removal.
-
Interpret important inspect evidence including container ID/name,
image identity,
.State.Status, PID, exit code, restart count, timestamps, command, labels, mounts, and networks. -
Explain why
execstarts an additional process whileattachconnects to the already-running primary process streams. - Relate precise lifecycle evidence to safe incident response, deployment automation, reproducibility, and rollback.
1. The problem: “the container is up” is not a lifecycle model
Operational mistakes begin when every Docker state is reduced to one sentence such as “the container is running.” Docker stores a container object containing configuration, image linkage, labels, mounts, network attachments, stop settings, and metadata. Starting that object asks the runtime to create a primary process. The process can exit while the container object remains available for inspection and another start. Removing the object is a separate action again.
This separation matters during incidents. If a process exits with
code 17, restarting it before capturing
.State.ExitCode, .State.FinishedAt, logs,
and image identity can blur the original failure. If an operator
force-removes the object, those Docker-level details disappear
completely. The chapter therefore treats lifecycle commands as state
transitions with evidence before and after each transition.
exec process, its human-readable name, and
the image it references are different identities. Preserve the
container ID and image digest when accuracy matters.
2. The lifecycle state machine
flowchart TD
I[Image + create configuration] --> C[Created container object\nno running PID 1]
C -->|docker start| R[Running\nprimary process exists]
R -->|docker exec| E[Additional exec process\nprimary process still owns lifecycle]
E --> R
R -->|docker pause| P[Paused\nprocesses suspended]
P -->|docker unpause| R
R -->|stop / process exits| X[Exited\nobject retained]
R -->|restart policy in progress| RR[Restarting]
RR --> R
X -->|docker start| R
X -->|docker restart| R
R -->|docker restart| R
X -->|docker rm| D[Removed\nDocker object gone]
C -->|docker rm| D
The Dead state is exceptional: Docker may know the
container should be gone or stopped but cleanup failed. It is not a
normal target state. Likewise, Paused and
Restarting are meaningful operational states, not
synonyms for “down.”
3. Identity: name, ID, image, and process PID
| Value | What it identifies | Can it change? | Operational use |
|---|---|---|---|
| Container name | Human-friendly Docker lookup name | Yes; it can be renamed and later reused after removal | Convenient commands and service conventions |
| Container ID | The Docker container object | Stable for the lifetime of that object | Incident evidence and exact cleanup |
| Image digest / image ID | The immutable image content selected for the container | Container keeps its configured image identity even if a tag later moves | Reproducibility and rollback |
.State.Pid |
Current primary host-side process ID where meaningful | Changes when the process is recreated/restarted | Runtime correlation, not container identity |
| Exec process | An additional process launched inside a running container | Short-lived; not the lifecycle owner | Bounded diagnostics/administration |
A restart illustrates the distinction: the container ID remains the same object, but the old primary process exits and a new primary process gets a new PID. A name is even weaker evidence because an operator can remove one container and create another with the same name.
4. Read-only inspection before any mutation
The safest first command is usually inspection. The following templates intentionally print lifecycle evidence without starting, stopping, or deleting anything:
docker ps -a --no-trunc
docker inspect CONTAINER --format \
'ID={{.Id}}
Name={{.Name}}
Image={{.Image}}
Status={{.State.Status}}
Running={{.State.Running}} Paused={{.State.Paused}} Restarting={{.State.Restarting}} Dead={{.State.Dead}}
Pid={{.State.Pid}} ExitCode={{.State.ExitCode}} RestartCount={{.RestartCount}}
StartedAt={{.State.StartedAt}} FinishedAt={{.State.FinishedAt}}
Path={{.Path}} Args={{json .Args}}
Labels={{json .Config.Labels}}
Mounts={{json .Mounts}}
Networks={{json .NetworkSettings.Networks}}'
Do not assume every field has the same meaning on every platform.
For example, host PID correlation is most direct on a native Linux
Engine; Docker Desktop inserts a managed VM boundary. Record
docker info and the active context alongside the
inspect output.
5. create, start, and
run change different things
docker create resolves an image and records a new
container object plus its configuration, but does not start the
primary process. docker start starts an existing
stopped/created object. docker run is a convenience
path that creates and starts a new object in one command. These are
not stylistic aliases when you care about evidence.
| Command | Container object | Primary process | Useful when |
|---|---|---|---|
docker create |
Creates new | Not started | You want to inspect final configuration before execution |
docker start |
Reuses existing | Starts/recreates primary process | You deliberately retained an object |
docker run |
Creates new | Starts immediately | Normal one-step workloads or disposable commands |
A common diagnostic error is repeatedly using
docker run while believing the same container is being
restarted. Each run normally creates another object unless the
command fails because a chosen name is already taken.
6. exec and attach are different
interactions
docker exec asks Docker to start an
additional command inside a running container.
Current Docker documentation is explicit that the exec command only
runs while the primary PID 1 is running and is not restarted when
the container restarts. It is useful for bounded inspection such as
reading a generated file or querying process state, but it is not an
image change or a durable repair.
docker attach does not start a new command. It connects
your terminal streams to the existing ENTRYPOINT/CMD process. That
means keystrokes and signals can affect the primary process. For
TTY-enabled containers, the default detach sequence
Ctrl-p Ctrl-q leaves the container running. For
non-interactive or performance-critical output, prefer
docker logs instead of holding an attach stream open.
7. Stop, kill, exit, and restart
docker stop attempts graceful shutdown: Docker sends
the container's configured stop signal (or SIGTERM when
none is configured) and waits for the configured timeout. If the
primary process has not exited, Docker escalates to
SIGKILL. docker kill defaults to immediate
SIGKILL, although a different signal can be requested.
docker restart performs a stop/start cycle on the same
container object. It is not the same concept as a
restart policy, which instructs the daemon whether
to restart containers automatically after exit or daemon restart.
The .RestartCount field is useful evidence but should
be interpreted with the configured restart policy and event
timeline.
Engine 29.7 introduced a daemon-level
default-stop-timeout option. Containers can also have
their own stop timeout. Do not hard-code “10 seconds” into
operational policy without inspecting the actual container and
platform; current Docker documentation notes different daemon
defaults for Linux and Windows containers when no explicit default
is configured.
8. Removal is not stopping
docker rm removes a Docker container object. A normal
running container is not silently stopped and removed by the basic
command. Force removal (docker rm -f) uses
SIGKILL on a running container, which is exactly why it
is a poor first troubleshooting step. It can erase inspectable state
and bypass application shutdown.
Likewise, docker rm -v has volume implications:
anonymous volumes associated with the container can be removed while
named volumes are treated differently. Storage lifecycle is taught
in depth later; Chapter 05 uses no persistent application volumes so
the cleanup boundary remains obvious.
9. Read state fields as an evidence packet, not a status badge
Created, running, paused, restarting, exited, or dead tells you the current Docker lifecycle classification.
Correlates the current primary process; zero/no meaningful PID when stopped and platform-dependent across Desktop/Windows boundaries.
Explains how the primary process terminated, but requires application/log context to explain why.
Helps reveal automatic restart behavior; interpret with policy and event timing.
StartedAt and FinishedAt anchor the
failure timeline.
Command, entrypoint, labels, mounts, networks, stop settings, and restart policy explain what Docker intended to run.
10. DevOps connection: lifecycle evidence makes automation safe
Reliable automation never asks only “did
docker run return zero?” A production-worthy chain
identifies the source image by digest, the exact container object,
the state transition requested, the resulting process identity,
logs/events/exit evidence, mounted data/network exposure, and
external service health. Those states can disagree.
For example, a container can be running while the
application inside is not ready; a process can exit cleanly while a
required external side effect failed; a restart can make the process
healthy while destroying the best first-failure evidence. Later
chapters add health checks, networking, persistent data, resource
policy, and security signals to this lifecycle model.
11. Common wrong mental models
- “A container is a process.” Better: Docker stores an object whose primary process can be absent, running, or replaced by restart.
- “The name is the identity.” Better: use container ID for exact object evidence; names are reusable labels.
- “Exec changes the container's startup command.” Better: exec launches a separate process; it does not rewrite the image or container command.
- “Attach opens a shell.” Better: attach connects to the existing primary process streams.
- “rm is cleanup, so it is harmless.” Better: deletion removes diagnostic state; force removal also kills the process.
- “Restart fixed it.” Better: restart changed state. Unless the causal failure is explained, the incident is not understood.
12. Small challenge: identify the state owner
A container named api is listed as
Exited (137). A teammate proposes
docker rm -f api && docker run --name api ....
Before accepting that plan, write down which evidence you would
preserve, which identity would be lost, whether -f adds
value to an already-exited object, and whether the replacement would
be the same container. Your answer should mention container ID,
image identity, exit code, timestamps, logs/events, restart policy,
mounts, networks, and any external application state.
Knowledge check
A container is Exited. Does the container object
still exist?
Yes. The primary process has ended, but Docker retains the object and its inspectable configuration/state until the object is removed.
After docker restart, which is expected to remain
stable: container ID or primary PID?
The container ID identifies the same object and remains stable. The primary process is recreated, so its PID can change.
Why is docker exec not a durable configuration
repair?
It starts an extra command in the running container. It does not change the source Dockerfile/image, and the exec process itself does not survive a container restart.
What is the key danger of docker rm -f during
first-failure diagnosis?
For a running container it uses SIGKILL and then removes the Docker object, potentially destroying valuable process and inspect evidence before the cause is understood.
Official references and version notes
- docker container command group — current container-management surface, including create, run, start, stop, restart, kill, rm, exec, attach, inspect, pause, and wait.
- docker container create — creates a container object without starting its primary process and records runtime configuration such as restart policy and stop timeout.
- docker container run — create-and-start convenience behavior, foreground/detached operation, automatic removal, signal proxying, and stop configuration.
- docker container start — starts an existing stopped container and optionally attaches standard streams.
- docker container stop — graceful stop signal, timeout, and eventual SIGKILL escalation semantics.
- docker container kill — immediate/default SIGKILL behavior and explicit signal selection.
- docker container restart — stop-then-start semantics, configurable signal, and timeout behavior.
-
docker container rm
— exact container removal; force-removing a running container uses
SIGKILL and
-vaffects anonymous volumes. - docker container exec — starts an additional command only while the container's primary PID 1 is running; exec commands are not automatically restarted with the container.
- docker container attach — attaches local standard streams to the existing ENTRYPOINT/CMD process, signal-proxy implications, detach keys, and throughput caveats.
- docker container inspect — low-level container configuration and state evidence, including PID, exit code, restart count, timestamps, mounts, and networks.
- Start containers automatically — restart-policy behavior, successful-start monitoring, manual-stop interaction, and distinction from live restore.
-
Docker Engine 29 release notes
— current Engine 29 baseline; Engine 29.7 added the daemon-level
default-stop-timeoutoption and 29.8.1 is the current patch release at chapter verification time.
Verified 2026-09-21: Docker Engine
29.8.1 is the current Engine 29 patch release.
Docker's current CLI documentation defines
docker exec as a command that exists only while the
container's primary process is running;
docker stop sends the configured stop signal and
escalates to SIGKILL after the timeout;
docker kill defaults to SIGKILL; and
docker rm --force kills a running container before
removing the object. Linux and Windows defaults and
process-isolation behavior differ, so every executable lab records
the actual client/server, OS type, architecture, stop
configuration, image digest, and container state observed on the
learner's environment.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.