| name | container-debug |
| description | Debug running Docker containers and Compose services. Use when inspecting container logs, exec-ing into running containers, diagnosing networking issues, checking resource usage, debugging multi-stage builds, troubleshooting health checks, or fixing Compose service dependencies. |
| metadata | {"clawdbot":{"emoji":"🐳","requires":{"bins":["docker"]},"os":["linux","darwin","win32"]}} |
Container Debug
Debug running Docker containers and Compose services. Covers logs, exec, networking, resource inspection, multi-stage builds, health checks, and common failure patterns.
When to Use
- Container exits immediately or crashes on start
- Application inside container behaves differently than on host
- Containers can't communicate with each other
- Container is using too much memory or CPU
- Multi-stage Docker build produces unexpected results
- Health checks are failing
- Compose services start in wrong order or can't connect
Container Logs
View and filter logs
docker logs --tail 100 my-container
docker logs -f my-container
docker logs -f -t my-container
docker logs --since 30m my-container
docker logs --since "2026-02-03T10:00:00" my-container
docker logs --since 1h --until 30m my-container
docker compose logs -f
docker compose logs -f api db
docker logs my-container > container.log 2>&1
docker logs my-container > stdout.log 2> stderr.log
Inspect log driver
docker inspect --format='{{.HostConfig.LogConfig.Type}}' my-container
docker inspect --format='{{.LogPath}}' my-container
ls -lh $(docker inspect --format='{{.LogPath}}' my-container)
Exec Into Containers
Interactive shell
docker exec -it my-container bash
docker exec -it my-container sh
docker exec -u root -it my-container bash
docker exec -e DEBUG=1 -it my-container bash
docker exec my-container cat /etc/os-release
docker exec my-container ls -la /app/
docker exec my-container env
Debug a crashed container
docker inspect --format='{{.State.ExitCode}}' my-container
docker inspect --format='{{.State.Error}}' my-container
docker start -ai my-container
docker run -it --entrypoint sh my-image
docker cp my-container:/app/error.log ./error.log
docker cp my-container:/etc/nginx/nginx.conf ./nginx.conf
Debug without a shell (distroless / scratch images)
docker cp my-container:/app/config.json ./
PID=$(docker inspect --format='{{.State.Pid}}' my-container)
nsenter -t $PID -m -u -i -n -p -- /bin/sh
docker run -it --pid=container:my-container --net=container:my-container busybox sh
docker debug my-container
Networking
Inspect container networking
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-container
docker inspect -f '{{json .NetworkSettings.Networks}}' my-container | jq
docker network ls
docker network inspect bridge
docker network inspect my-compose-network
docker port my-container
Test connectivity between containers
docker exec container-a ping container-b
docker exec container-a curl http://container-b:8080/health
docker exec my-container nslookup db
docker exec my-container cat /etc/resolv.conf
docker exec my-container cat /etc/hosts
docker exec my-container nc -zv db 5432
docker exec my-container wget -qO- http://api:3000/health
docker run --rm --network container:my-container curlimages/curl curl -s http://localhost:8080
Common networking issues
docker exec my-container netstat -tlnp
docker inspect -f '{{json .NetworkSettings.Networks}}' container-a | jq 'keys'
docker inspect -f '{{json .NetworkSettings.Networks}}' container-b | jq 'keys'
docker network create my-net
docker run --network my-net --name api my-api-image
docker run --network my-net --name db postgres
Capture network traffic
docker exec my-container tcpdump -i eth0 -n port 8080
docker run --rm --net=container:my-container nicolaka/netshoot tcpdump -i eth0 -n
docker run --rm --net=container:my-container nicolaka/netshoot bash
Resource Usage
Real-time stats
docker stats
docker stats api db redis
docker stats --no-stream
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
Memory investigation
docker inspect --format='{{.HostConfig.Memory}}' my-container
docker inspect --format='{{.State.OOMKilled}}' my-container
docker exec my-container cat /sys/fs/cgroup/memory.current 2>/dev/null || \
docker exec my-container cat /sys/fs/cgroup/memory/memory.usage_in_bytes
docker exec my-container ps aux --sort=-%mem | head -10
docker exec my-container top -bn1
Disk usage
docker system df
docker system df -v
docker inspect --format='{{.SizeRw}}' my-container
docker exec my-container du -sh /* 2>/dev/null | sort -rh | head -10
docker exec my-container find /tmp -size +10M -type f
docker exec my-container ls -lh /var/log/
Dockerfile Debugging
Multi-stage build debugging
docker build --target builder -t my-app:builder .
docker run --rm -it my-app:builder sh
docker run --rm my-app:builder ls -la /app/
docker run --rm my-app:builder cat /app/package.json
docker run --rm my-image ls -laR /app/
docker build --no-cache -t my-app .
docker build --progress=plain -t my-app .
Image inspection
docker history my-image
docker history --no-trunc my-image
docker inspect my-image | jq '.[0].Config | {Cmd, Entrypoint, Env, ExposedPorts, WorkingDir}'
docker history image-a --format "{{.Size}}\t{{.CreatedBy}}" > layers-a.txt
docker history image-b --format "{{.Size}}\t{{.CreatedBy}}" > layers-b.txt
diff layers-a.txt layers-b.txt
docker diff my-container
Health Checks
Define and debug health checks
# In Dockerfile
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/health || exit 1
docker inspect --format='{{.State.Health.Status}}' my-container
docker inspect --format='{{json .State.Health}}' my-container | jq
docker exec my-container curl -f http://localhost:8080/health
docker run --health-cmd "curl -f http://localhost:8080/health || exit 1" \
--health-interval 10s my-image
docker run --no-healthcheck my-image
Docker Compose Debugging
Service startup issues
docker compose ps
docker compose logs failed-service
docker compose up --build 2>&1 | tee compose.log
docker compose up db
docker compose up --no-deps api
docker compose up --force-recreate --build
docker compose config
Service dependency and startup order
services:
api:
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
timeout: 5s
retries: 5
redis:
image: redis:7
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
docker compose up -d db
docker compose exec db pg_isready
docker compose up -d api
Cleanup
docker container prune
docker image prune
docker system prune -a
docker system prune -a --volumes
docker builder prune
Tips
docker logs -f is the first thing to check. Most container failures are visible in the logs.
- Exit code 137 means OOM-killed. Increase the memory limit or fix the memory leak.
- Apps inside containers must bind to
0.0.0.0, not 127.0.0.1. Localhost inside a container is isolated.
- Container names only resolve via DNS on user-defined networks, not the default
bridge. Always create a custom network for multi-container setups.
docker exec only works on running containers. For crashed containers, use docker cp to extract logs or override the entrypoint with docker run --entrypoint sh.
nicolaka/netshoot is the Swiss Army knife for container networking. It has every networking tool pre-installed.
--progress=plain during builds shows full command output, which is essential for debugging build failures.
- Health checks with
start-period prevent false unhealthy status during slow application startup.