Docker — Debugging & Troubleshooting
Container Won't Start
docker logs myapp # Check startup errors
docker logs --tail 50 myapp # Last 50 lines
docker inspect myapp --format '{{.State.ExitCode}}' # Exit code
docker inspect myapp --format '{{.State.Error}}' # Error message
docker inspect myapp --format '{{json .State}}' | jq # Full state
| Exit Code | Meaning |
|---|---|
| 0 | Normal exit |
| 1 | Application error |
| 137 | OOM killed (SIGKILL) or docker kill |
| 139 | Segfault (SIGSEGV) |
| 143 | Graceful shutdown (SIGTERM) |
OOM Diagnosis
docker inspect myapp --format '{{.State.OOMKilled}}' # true = out of memory
docker stats --no-stream myapp # Check memory usage
# Fix: increase memory limit in compose deploy.resources.limits.memory
Network Debugging
DNS & Connectivity
docker compose exec api nslookup db # DNS resolution
docker compose exec api ping -c 3 db # ICMP connectivity
docker compose exec api curl -v http://db:5432 # TCP connectivity
docker compose exec api nc -zv db 5432 # Port check (netcat)
docker compose exec api timeout 5 bash -c 'cat < /dev/tcp/db/5432' # Alt port check
Network Inspection
docker network ls # List networks
docker network inspect mynet # Subnet, gateway, containers
# Show IP of every container on a network
docker network inspect mynet \
--format '{{range .Containers}}{{.Name}}: {{.IPv4Address}}{{"\n"}}{{end}}'
# Check which networks a container belongs to
docker inspect myapp --format '{{json .NetworkSettings.Networks}}' | jq
Netshoot Debug Container
When the application container has no shell or networking tools:
# Attach to same network
docker run --rm -it --network mynet nicolaka/netshoot
# Attach to container's network namespace directly
docker run --rm -it --network container:myapp nicolaka/netshoot
# Inside netshoot — full toolkit available:
# ping, curl, dig, nslookup, traceroute, tcpdump, ss, ip, iftop
Log Analysis
docker logs -f myapp # Follow live
docker logs --since 2026-03-31T10:00:00 myapp # Since timestamp (RFC3339)
docker logs --since 30m myapp # Last 30 minutes
docker logs -f myapp 2>&1 | grep -i error # Filter errors
docker logs -f myapp 2>&1 | grep -i -E "error|warn" # Errors + warnings
# Compose: all services
docker compose logs -f
docker compose logs -f --since 10m api db
Log File Location
# Find log file path
docker inspect myapp --format '{{.LogPath}}'
# Check log file size
ls -lh $(docker inspect myapp --format '{{.LogPath}}')
# Truncate logs (emergency — stops log collection temporarily)
truncate -s 0 $(docker inspect myapp --format '{{.LogPath}}')
Filesystem & Process Debugging
docker exec -it myapp /bin/sh # Shell into container
docker exec -it myapp ls -la /app # List files
docker exec -it myapp cat /etc/os-release # Check base OS
docker exec -it myapp env # Environment variables
docker top myapp # Processes (from host)
docker exec myapp ps aux # Processes (from container)
docker diff myapp # Filesystem changes vs image
# A = added, C = changed, D = deleted
Resource Issues
docker stats # Live CPU / memory / IO
docker stats --no-stream --format \
"table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.MemPerc}}\t{{.NetIO}}"
docker system df # Disk usage by type
docker system df -v # Per-image/container breakdown
# Disk full? Clean up:
docker system prune -a --volumes # Remove everything unused
docker image prune -a # Remove unused images
docker volume prune # Remove unused volumes
docker builder prune # Clear build cache
Compose-Specific Debugging
docker compose config # Validate and show resolved YAML
docker compose config --services # List service names
docker compose ps # Service status + ports
docker compose top # Processes across all services
# Recreate specific service (picks up config changes)
docker compose up -d --force-recreate api
# Rebuild and restart
docker compose up -d --build api
# Check why a service keeps restarting
docker compose logs --tail 20 api
docker inspect $(docker compose ps -q api) --format '{{.RestartCount}}'
Build & Health Debugging
docker build --progress=plain -t myapp . # Verbose build output
docker build --target builder -t myapp:builder . # Build specific stage
docker history myapp:latest # Layer history
docker run --rm -it myapp:builder /bin/sh # Enter build stage
docker builder prune -a # Clear build cache
docker inspect myapp --format '{{json .State.Health}}' | jq # Health status
docker exec myapp curl -f http://localhost:8000/health # Manual check
Troubleshooting Decision Tree
Container won't start?
├── Check: docker logs myapp
├── Exit 137? → OOM → increase memory limit
├── Exit 1? → App error → check logs for stack trace
└── Permission denied? → Check USER + volume ownership
Can't connect to service?
├── docker compose ps → is it running?
├── nslookup <service> → DNS resolves?
├── nc -zv <host> <port> → port open?
├── docker network inspect → same network?
└── Check firewall / security groups
Performance issues?
├── docker stats → CPU/memory usage
├── docker system df → disk pressure
├── docker logs → error loops / retries
└── docker top myapp → runaway processes
Build slow?
├── Layer caching → deps before source code
├── .dockerignore → exclude unnecessary files
├── BuildKit → DOCKER_BUILDKIT=1
└── Cache mounts → --mount=type=cache