Topic 10.3
Debugging Containers: logs, exec, inspect, events & debug containers
In one line
When a container crashes, restarts, or hangs, a fixed sequence finds the answer: status and exit code, logs, inspect, events, then get inside the namespaces, even for distroless images with no shell.
Think of it like this
A mechanic with a car that won't start. First the dashboard lights (status, exit code), then the error log (logs), then the service record (inspect), then recent events (who touched it), and finally opening the bonnet with their own tools (a debug container).
Key ideas
- 01
STATUS and EXIT CODES:
docker ps -ashowsExited (137)= SIGKILL, usually OOM (docker inspect -f '{{.State.OOMKilled}}');(143)= SIGTERM (stopped normally);(1)= the app crashed, check logs;(126/127)= the command isn't executable or not found (wrong ENTRYPOINT, missing binary, wrong architecture: 'exec format error'). - 02
LOGS and INSPECT:
docker logs --tail 100 -f --timestamps api(logs survive the container stopping, until it's removed),docker inspect api(env, mounts, network, restart count, health log).docker events --since 30mshows the timeline: die, oom, restart, health_status changes. - 03
GETTING INSIDE:
docker exec -it api shif the image has a shell. For DISTROLESS or scratch images with no shell, attach a debug container that shares the target's namespaces:docker debug api(Docker Desktop/Pro), ordocker run -it --rm --pid container:api --network container:api nicolaka/netshootto get full networking and process tools in the same namespaces. On a host,nsenter -t <pid> -n -penters namespaces directly (Phase 9). - 04
NETWORK PROBLEMS: from inside the container's network namespace, test DNS (
getent hosts db), connectivity (nc -vz db 5432), and what's listening (ss -ltnp). Typical culprits: the app listening on127.0.0.1instead of0.0.0.0(so the published port doesn't work), a wrong network (containers on different networks can't resolve each other's names), or usinglocalhostto reach another container (Phase 4). - 05
RESOURCE PROBLEMS:
docker stats(live CPU, memory against limit, I/O),docker top api(processes inside), cgroup files for throttling counts (Phase 9). Crash-looping container?docker run --entrypoint shwith the same image and env to explore interactively.
Code & diagrams
docker ps -a --filter name=api --format '{{.Names}} {{.Status}}' # Exited (137) 2 minutes ago
docker inspect -f '{{.State.OOMKilled}} restarts={{.RestartCount}}' api
docker logs --tail 50 --timestamps api
docker events --since 30m --filter container=api
docker stats --no-stream api
# distroless image, no shell: borrow tools in the same namespaces
docker run -it --rm --pid container:api --network container:api nicolaka/netshoot \
sh -c 'ss -ltnp; getent hosts db; nc -vz db 5432'Explain it without notes
The app runs fine with docker run locally but curl localhost:8080 from the host gets 'connection reset'. What's the most likely cause?
Practice
A container restarts every 90 seconds with exit code 137, but memory looks fine in docker stats. What else could send SIGKILL?
Done when you can
I can triage a container by exit code, logs, inspect, and events
I can debug a distroless container by sharing its namespaces with a tools container