When containers misbehave — crashing on startup, running slowly, or producing unexpected behavior — systematic debugging is essential. This guide covers the complete toolkit for diagnosing Docker container issues, from simple log inspection to advanced debugging techniques.
Container Logs
# View logs
docker logs container_name
# Follow logs in real-time
docker logs -f container_name
# Last N lines
docker logs --tail 100 container_name
# Logs since a timestamp
docker logs --since "2025-01-15T10:00:00" container_name
# Logs with timestamps
docker logs -t container_name
# Docker Compose logs
docker compose logs -f service_name
Container Inspection
# Full container details
docker inspect container_name
# Specific fields
docker inspect --format='{{.State.Status}}' container_name
docker inspect --format='{{.State.ExitCode}}' container_name
docker inspect --format='{{json .State}}' container_name | jq
docker inspect --format='{{json .Config.Env}}' container_name | jq
docker inspect --format='{{json .NetworkSettings.Networks}}' container_name | jq
docker inspect --format='{{.HostConfig.Memory}}' container_name
# Check restart count and last exit
docker inspect --format='{{.RestartCount}}' container_name
docker inspect --format='{{.State.OOMKilled}}' container_name
Executing Commands in Containers
# Interactive shell
docker exec -it container_name /bin/bash
docker exec -it container_name /bin/sh # Alpine images
# Run a specific command
docker exec container_name cat /etc/nginx/nginx.conf
docker exec container_name env
docker exec container_name ps aux
docker exec container_name df -h
# As root (if container runs as non-root)
docker exec -u root -it container_name /bin/bash
Debugging Crashed Containers
# Container won't start — check exit code
docker ps -a | grep container_name
# EXIT CODE meanings:
# 0 — exited normally
# 1 — application error
# 137 — killed by OOM or docker kill (128 + SIGKILL=9)
# 139 — segmentation fault (128 + SIGSEGV=11)
# 143 — graceful termination (128 + SIGTERM=15)
# Run interactively to see startup errors
docker run -it image_name /bin/bash
# Override entrypoint to debug
docker run -it --entrypoint /bin/sh image_name
# Check last container logs even if crashed
docker logs $(docker ps -a -q -f name=container_name)
Networking Debugging
# Check container networking
docker exec container_name ip addr
docker exec container_name cat /etc/resolv.conf
# Test connectivity between containers
docker exec web ping db
docker exec web nslookup db
docker exec web curl -v http://api:8080/health
# Install debugging tools in running container
docker exec -u root container_name apt update && apt install -y curl iputils-ping dnsutils
# Check port bindings
docker port container_name
docker inspect --format='{{json .NetworkSettings.Ports}}' container_name | jq
File System Inspection
# Copy files from container
docker cp container_name:/app/logs/error.log ./error.log
# Copy files to container
docker cp config.yaml container_name:/app/config.yaml
# Diff container filesystem vs image
docker diff container_name
# A = added, C = changed, D = deleted
# View container filesystem as tarball
docker export container_name > container-fs.tar
Resource Debugging
# Real-time resource usage
docker stats container_name
# Process list inside container
docker top container_name
# Check for OOM kills
docker inspect --format='{{.State.OOMKilled}}' container_name
dmesg | grep -i "container_name\|oom"
# Container events
docker events --filter container=container_name --since "1h"
Docker Debug (Docker Desktop)
# Docker Debug provides a debugging shell for any container
docker debug container_name
# Includes pre-installed tools: vim, curl, htop, strace, tcpdump, etc.
# Works even on minimal/distroless images
Health Check Debugging
# View health check status
docker inspect --format='{{json .State.Health}}' container_name | jq
# Health check logs
docker inspect --format='{{range .State.Health.Log}}{{.Output}}{{end}}' container_name
Best Practices
- Always check exit codes first — they often point directly to the problem
- Use
--entrypoint /bin/shto override startup and debug interactively - Check OOM kills when containers mysteriously restart
- Use
docker eventsto see a timeline of container lifecycle events - Keep a debugging image with tools pre-installed for network-namespace debugging
- Enable health checks in all production containers for early problem detection