Docker
Beginner 13 min read Docker

Docker Containers & Lifecycle

A container is a running, isolated instance of an image. Master start, stop, exec, logs and cleanup, and understand why the main process defines its lifecycle.

lifecyclePID 1execlogsexit codesrestart policies
Introduction

What is this?

A container is the runtime instance of an image. Docker starts the image's configured command as a process with its own namespaces and filesystem, and the container lives exactly as long as that main process runs. When the main process exits, the container stops.

Motivation

Why do you need it?

  • Each container gives an app its own filesystem, network stack and PID namespace for isolation.
  • Lifecycle tied to one process makes containers predictable and scriptable.
  • Restart policies make containers self-healing without an orchestrator.
  • Logs are centralized on stdout/stderr, which every logging pipeline can consume.
Think about it

Mental model

Imagine

A process on your laptop

Think of

A container

A container is really just a process — with a private filesystem, network and PID space. Start it, and it runs until its main process exits.

Mechanics

How it works

  • docker run = create container from image + start its main process.
  • The main process becomes PID 1 inside the container's PID namespace.
  • When PID 1 exits, the container transitions to 'exited' with that process's exit code.
  • docker exec runs an additional process inside the same namespaces (common for debugging).
  • Restart policies (unless-stopped, always, on-failure) tell the daemon to restart exited containers.

Container lifecycle states.

docker run
Running
docker stop / exit
Exited
docker rm
Reference

Key commands

docker run -d --name web nginx

Run a container in the background with a friendly name.

docker ps

List only running containers.

docker stop -t 5 web

Gracefully stop, waiting up to 5s then SIGKILL.

docker exec -it web sh

Open an interactive shell inside a running container.

docker logs --tail 50 web

Show the last 50 log lines of the main process.

Hands-on

Examples

Container lifecycle in one line

Container lifecycle in one line
docker run -d --name api --restart unless-stopped -p 3000:3000 myapp:1.0
docker logs -f api
docker exec -it api sh
docker stop api
docker rm api

Starts the app detached with an auto-restart policy, then shows live logs, opens a shell inside the running container, and finally stops and removes it.

Real world

In production

  • Containers are treated as disposable: deploy by creating new ones, never by patching running ones.
  • Restart policies keep services alive on the host until an orchestrator takes over.
  • docker logs feeds stdout to centralized logging (EFK, Loki, Datadog).
  • Health checks (docker healthcheck) surface liveness for load balancers and orchestrators.
Guidelines

Best practices

  • Make the app the main process and let it handle signals — or the container won't stop cleanly.
  • Use restart unless-stopped for long-running services on a single host.
  • Keep containers stateless; use volumes for anything that must survive.
  • Set a healthcheck so status reflects real readiness, not just process liveness.
Watch out

Common mistakes

  • Running multiple unrelated processes in one container without a supervisor.
  • Relying on the shell PID instead of the real app so signals are ignored.
  • Starting long-running services with docker run --rm without understanding it deletes the container on exit.
  • Ignoring the exit code — docker inspect shows it in State.ExitCode.
Root cause analysis

Common issues

Error
Container exits immediately (ExitCode 0)
Root cause

Main process is a shell or command that returns immediately, so the container has nothing to keep alive.

Fix

Run a long-lived foreground process (e.g. CMD ["nginx","-g","daemon off;"]) or tail -f /dev/null for testing.

Error
Container won't stop gracefully
Root cause

The main process ignores SIGTERM (e.g. a shell wrapping your app).

Fix

Use a signal-forwarding process (tini / dumb-init) as PID 1, and exec the app so it receives signals directly.

Error
OOMKilled
Root cause

The container exceeded its memory cgroup limit.

Fix

Check docker inspect for Memory and OOMKilled, raise --memory, or fix the memory leak.

When things break

Debugging tips

  • docker ps -a to see exited containers and their IDs.
  • docker inspect -f '{{.State.ExitCode}} {{.State.Error}}' ID for crash details.
  • docker logs ID to see why the process exited.
  • docker exec -it ID sh to inspect a still-running container.
Interviews

Interview checkpoint

Practice

Hands-on lab

Container Lifecycle & Debugging
25 min · beginner
In progress
Objectives
  • Start and manage container lifecycle
  • Read logs and exit codes
  • Exec into a running container
  • Troubleshoot an immediate-exit container

Container Lifecycle & Debugging

25 min · beginner

0/5 steps
0%
sandbox · Linux sandbox
$
Try these commands
Test yourself

Quick quiz

0/2
1

Which command opens an interactive shell inside a running container?

2

A container with a restart policy of 'always' restarts after...

Quick reference

Cheat sheet

Lifecycle
docker run -d --name X IMGDetached run with name
docker stop -t 10 XGraceful stop (10s timeout)
docker rm -f XForce remove running container
docker exec -it X shShell into container
Go deeper

Official documentation