Container Debug
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
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
Real data. Real impact.
Emerging
Developers
Per week
Open source
Skills give you superpowers. Install in 30 seconds.
Debug running Docker containers and Compose services. Covers logs, exec, networking, resource inspection, multi-stage builds, health checks, and common failure patterns.
# Last 100 lines docker logs --tail 100 my-containerFollow (stream) logs
docker logs -f my-container
Follow with timestamps
docker logs -f -t my-container
Logs since a time
docker logs --since 30m my-container docker logs --since "2026-02-03T10:00:00" my-container
Logs between times
docker logs --since 1h --until 30m my-container
Compose: logs for all services
docker compose logs -f
Compose: logs for specific service
docker compose logs -f api db
Redirect logs to file for analysis
docker logs my-container > container.log 2>&1
Separate stdout and stderr
docker logs my-container > stdout.log 2> stderr.log
# Check what log driver a container uses docker inspect --format='{{.HostConfig.LogConfig.Type}}' my-containerIf json-file driver, find the actual log file
docker inspect --format='{{.LogPath}}' my-container
Check log file size
ls -lh $(docker inspect --format='{{.LogPath}}' my-container)
# Bash (most common) docker exec -it my-container bashIf bash isn't available (Alpine, distroless)
docker exec -it my-container sh
As root (even if container runs as non-root user)
docker exec -u root -it my-container bash
With specific environment variables
docker exec -e DEBUG=1 -it my-container bash
Run a single command (no interactive shell)
docker exec my-container cat /etc/os-release docker exec my-container ls -la /app/ docker exec my-container env
# Container exited? Check exit code docker inspect --format='{{.State.ExitCode}}' my-container docker inspect --format='{{.State.Error}}' my-containerCommon exit codes:
0 = clean exit
1 = application error
137 = killed (OOM or docker kill) — 128 + signal 9
139 = segfault — 128 + signal 11
143 = terminated (SIGTERM) — 128 + signal 15
Start a stopped container to debug it
docker start -ai my-container
Or override the entrypoint to get a shell
docker run -it --entrypoint sh my-image
Copy files out of a stopped container
docker cp my-container:/app/error.log ./error.log docker cp my-container:/etc/nginx/nginx.conf ./nginx.conf
# Use docker cp to extract files docker cp my-container:/app/config.json ./Use nsenter to get a shell in the container's namespace (Linux)
PID=$(docker inspect --format='{{.State.Pid}}' my-container) nsenter -t $PID -m -u -i -n -p -- /bin/sh
Attach a debug container to the same namespace
docker run -it --pid=container:my-container --net=container:my-container busybox sh
Docker Desktop: use debug extension
docker debug my-container
# Show container IP address docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' my-containerShow all network details
docker inspect -f '{{json .NetworkSettings.Networks}}' my-container | jq
List all networks
docker network ls
Inspect a network (see all connected containers)
docker network inspect bridge docker network inspect my-compose-network
Show port mappings
docker port my-container
# From inside container A, reach container B docker exec container-a ping container-b docker exec container-a curl http://container-b:8080/healthDNS resolution inside container
docker exec my-container nslookup db docker exec my-container cat /etc/resolv.conf docker exec my-container cat /etc/hosts
Test if port is reachable
docker exec my-container nc -zv db 5432 docker exec my-container wget -qO- http://api:3000/health
If curl/ping not available in container, install or use a debug container:
docker run --rm --network container:my-container curlimages/curl curl -s http://localhost:8080
# "Connection refused" between containers # 1. Check the app binds to 0.0.0.0, not 127.0.0.1 docker exec my-container netstat -tlnp # If listening on 127.0.0.1 — fix the app config2. Check containers are on the same network
docker inspect -f '{{json .NetworkSettings.Networks}}' container-a | jq 'keys' docker inspect -f '{{json .NetworkSettings.Networks}}' container-b | jq 'keys'
3. Check published ports vs exposed ports
EXPOSE only documents, it doesn't publish
Use -p host:container to publish
"Name not found" — DNS not resolving container names
Container names resolve only on user-defined networks, NOT the default bridge
docker network create my-net docker run --network my-net --name api my-api-image docker run --network my-net --name db postgres
Now "api" and "db" resolve to each other
# tcpdump inside a container docker exec my-container tcpdump -i eth0 -n port 8080If tcpdump not available, use a sidecar
docker run --rm --net=container:my-container nicolaka/netshoot tcpdump -i eth0 -n
netshoot has: tcpdump, curl, nslookup, netstat, iperf, etc.
docker run --rm --net=container:my-container nicolaka/netshoot bash
# All containers docker statsSpecific containers
docker stats api db redis
One-shot (no streaming)
docker stats --no-stream
Formatted output
docker stats --format "table {{.Name}}\t{{.CPUPerc}}\t{{.MemUsage}}\t{{.NetIO}}"
# Check memory limit docker inspect --format='{{.HostConfig.Memory}}' my-container # 0 means unlimitedCheck if container was OOM-killed
docker inspect --format='{{.State.OOMKilled}}' my-container
Memory usage breakdown (Linux cgroups)
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_bytesProcess memory inside container
docker exec my-container ps aux --sort=-%mem | head -10 docker exec my-container top -bn1
# Overall Docker disk usage docker system df docker system df -vContainer filesystem size
docker inspect --format='{{.SizeRw}}' my-container
Find large files inside container
docker exec my-container du -sh /* 2>/dev/null | sort -rh | head -10 docker exec my-container find /tmp -size +10M -type f
Check for log file bloat
docker exec my-container ls -lh /var/log/
# Build up to a specific stage docker build --target builder -t my-app:builder .Inspect what's in the builder stage
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
Check which files made it to the final image
docker run --rm my-image ls -laR /app/
Build with no cache (fresh build)
docker build --no-cache -t my-app .
Build with progress output
docker build --progress=plain -t my-app .
# Show image layers (size of each) docker history my-image docker history --no-trunc my-imageInspect image config (entrypoint, cmd, env, ports)
docker inspect my-image | jq '.[0].Config | {Cmd, Entrypoint, Env, ExposedPorts, WorkingDir}'
Compare two images
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
Find what changed between builds
docker diff my-container
A = added, C = changed, D = deleted
# In Dockerfile HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \ CMD curl -f http://localhost:8080/health || exit 1
# Check health status docker inspect --format='{{.State.Health.Status}}' my-container # "healthy", "unhealthy", or "starting"See health check log (last 5 results)
docker inspect --format='{{json .State.Health}}' my-container | jq
Run health check manually
docker exec my-container curl -f http://localhost:8080/health
Override health check at run time
docker run --health-cmd "curl -f http://localhost:8080/health || exit 1"
--health-interval 10s my-imageDisable health check
docker run --no-healthcheck my-image
# Check service status docker compose psSee why a service failed
docker compose logs failed-service
Start with verbose output
docker compose up --build 2>&1 | tee compose.log
Start a single service (with dependencies)
docker compose up db
Start without dependencies
docker compose up --no-deps api
Recreate containers from scratch
docker compose up --force-recreate --build
Check effective config (after variable substitution)
docker compose config
# docker-compose.yml services: api: depends_on: db: condition: service_healthy redis: condition: service_starteddb: 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
# Wait for a service to be healthy before running commands docker compose up -d db docker compose exec db pg_isready # Polls until ready docker compose up -d api
# Remove stopped containers docker container pruneRemove unused images
docker image prune
Remove everything unused (containers, images, networks, volumes)
docker system prune -a
Remove volumes too (WARNING: deletes data)
docker system prune -a --volumes
Remove dangling build cache
docker builder prune
docker logs -f is the first thing to check. Most container failures are visible in the logs.0.0.0.0, not 127.0.0.1. Localhost inside a container is isolated.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.start-period prevent false unhealthy status during slow application startup.No automatic installation available. Please visit the source repository for installation instructions.
View Installation Instructions1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.