DOCKER CONTAINER LIFECYCLE — FROM ZERO TO ADVANCED LEVEL
A Docker container goes through a full lifecycle just like a Linux process, but with additional layers:
Image pulling
Filesystem creation (UnionFS)
Namespace + cgroup setup
Network setup
Entry process execution
Stop / restart / remove
Cleanup (volumes/networks)
Let’s start from the absolute beginning.
1️⃣ PRE-STAGE: Image Preparation
Before a container exists, Docker must prepare the image:
Steps
1.docker pull ubuntu
2.Docker stores image layers under /var/lib/docker//
3.A parent filesystem is prepared using UnionFS (overlay2).
No namespaces yet.
Only when we create or run the container, Docker sets namespaces.
2️⃣ CREATION STAGE: docker create
docker create prepares the container without starting the process.
docker create --name myc ubuntu sleep 100
What happens internally
1.Docker allocates a Container ID
2.Prepares the read-write layer over the image’s read-only layers
3.Creates a container metadata JSON in:
/var/lib/docker/containers//config.v2.json
Namespace creation happens here (critical)
Docker sets up namespaces but does not attach the process yet.
Namespaces created:
Namespace purpose:
mnt: Container filesystem mount points
pid: Separate process tree
uts: Hostname/domainname inside container
ipc: Shared memory, semaphores
net: Virtual Ethernet (veth) + network stack
user :(optional) UID/GID mapping
Namespaces are pre-configured, but NO process is running yet inside them.
Container State after docker create
State: created
You can check:
docker ps -a
3️⃣ START STAGE: docker start
docker start myc
This is when the real Linux process (container entrypoint) starts.
What happens internally
1.Docker forks a child process under container namespaces.
2.Applies cgroups:
CPU, Memory, PID limits
3.Sets rootfs using chroot + pivot_root
4.Executes entrypoint/CMD (like sleep 100).
Namespaces ACTIVE NOW
The process is running inside:
PID namespace (process 1 inside container)
Network namespace (separate network stack)
MNT namespace (isolated filesystem)
IPC namespace
UTS namespace
cgroups apply resource limits
Container State:
✔ running
Check via:
docker inspect -f '{{.State.Status}}' myc
4️⃣ RUNNING STATE — Active Execution
Container is now:
Running main PID
Attached to cgroups
Using its own namespaces
Maintaining logs
Connected to docker0 / bridge / custom network
When do we use this state?
✔ During application execution
✔ For monitoring logs
✔ For debugging using nsenter
✔ For updating filesystems, hot-changes, live testing
Entering namespaces of running container:
nsenter --target $(docker inspect -f '{{.State.Pid}}' myc) --pid --net --uts --ipc --mnt bash
5️⃣ PAUSED STATE (Advanced)
docker pause myc
Uses cgroups freezer subsystem.
Container process is frozen—not killed, not stopped.
When & where used? ✔ Debugging complex apps
✔ Troubleshooting race conditions
✔ Resource management
State: paused
Resume:
docker unpause myc
6️⃣ STOPPED STATE
Stopping a container:
docker stop myc
Internally:
1.Sends SIGTERM
2.Wait (default 10 sec)
3.If still alive → SIGKILL
Namespaces are destroyed only after process dies.
State: exited
Where used? ✔ Container upgrades
✔ Controlled shutdown
✔ Restart policies
✔ Debugging containers post-failure
7️⃣ RESTARTED STATE
If container has a restart policy:
docker run --restart=always ...
Docker will:
1.Stop existing process
2.Recreate minimal namespaces
3.Restart process
State temporarily = restarting
8️⃣ DEAD STATE
A rare state:
docker inspect
State: dead
Occurs when:
Docker daemon crashes during container operation
Filesystem or metadata corruption
Container kill failed
Used only for troubleshooting.
9️⃣ REMOVAL STAGE
docker rm myc
Internal actions:
1.Remove container metadata
2.Remove RW layer
3.Delete network namespace
4.Close logs
State: container no longer exists
🔟 POST-STAGE: Cleanups
Volume cleanup
docker volume rm
Network cleanup
docker network rm
🧠 DETAILED FINAL LIFECYCLE FLOW
IMAGE → create → (created)
→ start → (running)
→ pause/unpause (optional)
→ stop → (exited)
→ restart → (running)
→ kill → (exited)
→ rm → (removed)
Namespaces Involvement in Each Docker Container Lifecycle Stage:
When you run a container, namespaces do not suddenly appear at all stages. They participate differently depending on the container's state. Here is the correct and practical explanation in plain, continuous text:
1️⃣ docker create — Namespaces are prepared but not active
When you run docker create, Docker sets up the container’s configuration, root filesystem, and metadata.
At this stage, the namespaces are defined but no process has entered them yet.
There is no PID, no running task, so the namespaces exist only as a “plan”, not as an active isolation environment.
2️⃣ docker start — Process joins the namespaces
When you run docker start, Docker launches the container’s first process (PID 1).
This is the moment the process actually enters all namespaces: PID, NET, IPC, MOUNT, UTS, USER (if used).
So at this stage, the namespaces become active and isolate the process.
This is the real birth of the container.
3️⃣ Running state — Namespaces fully active
In the running state, the container is fully isolated using all its namespaces.
The process (PID 1) runs inside:
its own PID namespace,
its own network namespace,
its own mount namespace,
its own hostname/UTS namespace,
its own IPC namespace, etc.
This is the stage where namespaces are working at 100%.
4️⃣ Pause state — Namespaces unchanged
When you pause a container, Docker freezes the container’s processes using the cgroup freezer.
The processes stop executing instructions, but the namespaces remain exactly as they were.
Nothing changes in namespace setup.
Only process execution is temporarily stopped.
It’s like freezing a VM — all isolation stays intact.
5️⃣ Stop state — Namespaces removed once the process dies
When you stop a container, the main process receives SIGTERM → SIGKILL and exits.
As soon as the last process in the container dies, its namespaces are automatically destroyed because namespaces cannot exist without a process inside them.
Only container metadata remains; the isolation environment is gone.
DOCKER CONTAINER STATES — WHEN, WHY, AND REAL USAGE
Docker container states:
created → running → paused → exited → restarting → dead
Let’s explain each state:
1️⃣ CREATED STATE
➡ Happens when you run:
docker create ...
✔ When/Why You Use It
You use this state when:
1.You want to prepare a container but NOT run it yet
Example: Setting configuration or modifying filesystem before start.
docker create --name web nginx
docker cp custom.conf web:/etc/nginx/
docker start web
2.Pre-provisioning containers in CI/CD
Prepare them first → start later in batch.
3.Debugging container filesystem BEFORE RUN
Some engineers inspect root filesystem before app starts.
Reason this state exists:
It allows you to prepare everything about a container before running the main process, just like creating a VM but not powering it on.
2️⃣ RUNNING STATE
➡ Happens when the container’s main PID is active.
✔ When/Why You Use It
1.Application is actively running
Containers serve traffic or jobs.
2.Debug running services
You attach, exec, inspect logs:
docker exec -it cont bash
docker logs cont
3.Monitoring CPU, memory, IO
Using cgroups metrics.
4.Live troubleshooting
Check active network namespace, mounts, PIDs:
nsenter --target $(docker inspect -f '{{.State.Pid}}' cont) --net
Reason:
This is the actual “life” of the container — the application is fully executing.
3️⃣ PAUSED STATE
docker pause cont
Freezes the processes using cgroup freezer.
✔ When/Why You Use PAUSE
1.Debugging race conditions
Freeze container A, test container B for isolation.
2.Hot-maintenance of underlying host
Temporarily freeze containers without stopping them.
3.Resource protection
If container is consuming too much CPU, pause it without killing.
4.Live migration (rare)
Some orchestrators freeze containers before checkpoint/restore.
Reason:
Pause allows you to freeze running processes without killing them, useful for debugging, tuning, and resource control.
4️⃣ EXITED (STOPPED) STATE
docker stop cont
docker kill cont
✔ When/Why You Use EXITED
1.Stop app safely
docker stop gives graceful shutdown (SIGTERM → SIGKILL)
2.Keep logs and data for post-analysis
Stopped containers retain filesystem and logs.
3.Restart after configuration changes
Stop → modify → start again.
4.Investigate why app failed
Exit code:
docker inspect cont --format '{{.State.ExitCode}}'
5.CI pipelines
After job finishes, container moves to “exited”.
Reason:
Exited state keeps the container intact so DevOps can analyze, restart, debug, or fix problems without deleting it.
5️⃣ RESTARTING STATE
Happens when:
docker run --restart=always ...
✔ When/Why You Use RESTARTING
1.Autorecovery
If application crashes, Docker restarts it automatically.
2.Host reboot
All containers restart automatically (if policy is set).
3.Self-healing services
Basic container-level reliability even without Kubernetes.
Reason:
Makes container highly available even without orchestrators.
6️⃣ DEAD STATE
Rare state, appears only on issues.
✔ When/Why It Appears
1.Docker daemon crashed mid-operation
Container metadata becomes inconsistent.
2.Filesystem or cgroups failure
3.Force kill gone wrong
Docker couldn’t clean PID or release namespace.
Reason:
Dead state is for troubleshooting broken containers.
It indicates corruption or incomplete removal.
✔ When DevOps uses namespaces?
1.Network debugging
nsenter --net --target
ip a
2.Filesystem debugging
nsenter --mnt ...
mount
3.Security isolation testing
Check if apps see host processes:
nsenter --pid ...
ps -ef
4.IP/route issues
Debug inside container network namespace.
Top comments (0)