Docker Logs and Debugging a Running Container
Things go wrong. A container exits unexpectedly, an app throws errors, a service does not start. Knowing how to read logs and debug containers is one of the most valuable Docker skills you can have. This topic covers every tool for diagnosing problems.
Reading Container Logs
Docker captures everything a container writes to stdout and stderr. The docker logs command reads this output.
View all logs from a container: docker logs webapp Follow logs in real-time (like tail -f): docker logs -f webapp Show last 50 lines: docker logs --tail 50 webapp Show logs with timestamps: docker logs --timestamps webapp Combine: last 100 lines, follow, with timestamps: docker logs --tail 100 -f --timestamps webapp
Understanding Log Output
docker logs webapp 2024-01-15T10:23:01.123Z INFO Starting server on port 5000 2024-01-15T10:23:01.456Z INFO Connected to database 2024-01-15T10:23:02.789Z ERROR Failed to connect to Redis: Connection refused 2024-01-15T10:23:02.790Z WARN Retrying in 5 seconds... Reading this tells you: - Server started OK - Database connected OK - Redis connection FAILED ← this is your problem - It is retrying automatically
Debugging a Container That Fails to Start
A container starts and immediately exits. This is one of the most confusing situations for beginners. The container runs, fails, stops — and docker ps shows nothing.
Step 1: Find the stopped container
docker ps -a
CONTAINER ID IMAGE STATUS NAMES
a1b2c3d4e5f6 webapp Exited (1) 5 seconds ago my-webapp
Step 2: Read its logs (logs survive even after container exits)
docker logs a1b2c3d4e5f6
Error: Cannot find module '/app/dist/server.js'
at Function.Module._resolveFilename
Step 3: The error tells you the compiled file is missing
Fix: Run npm run build before docker run, or fix the Dockerfile
Inspecting a Container's Configuration
docker inspect webapp
This returns a large JSON object. Useful sections to look at:
"State": {
"Status": "running",
"ExitCode": 0,
"Error": ""
}
→ Check if container crashed and why
"HostConfig": {
"Binds": ["/home/user/data:/app/data"],
"PortBindings": {"5000/tcp": [{"HostPort": "5000"}]}
}
→ Verify volumes and port mappings are correct
"NetworkSettings": {
"IPAddress": "172.17.0.2",
"Ports": {"5000/tcp": ...}
}
→ Check network configuration
Getting a Shell Inside a Running Container
docker exec -it webapp bash
Once inside, you can investigate the container like you would any Linux system:
ls /app/ → check if files are where you expect cat /app/config.json → inspect configuration files env → check environment variables ps aux → see running processes netstat -tlnp → check what ports are listening curl localhost:5000 → test the app from inside the container
For minimal images (like Alpine) that do not have bash:
docker exec -it webapp sh ← use sh instead
Debugging a Container That Has Already Exited
You cannot exec into a stopped container. But you can start a fresh container from the same image with a shell — overriding the normal startup command:
docker run -it --entrypoint bash my-python-app
Now you are inside a container built from the same image. You can check file paths, verify configurations, and test commands manually.
Checking Resource Usage
docker stats CONTAINER CPU % MEM USAGE/LIMIT NET I/O BLOCK I/O webapp 82.5% 450MiB / 2GiB 1.2GB / 200MB 10MB / 0B db 5.2% 1.1GiB / 2GiB 50MB / 500MB 2GB / 1GB High CPU on webapp? → check for infinite loops, runaway queries High memory? → potential memory leak High block I/O? → disk-heavy operations, check database queries
Viewing Events
Docker records lifecycle events for every container. This helps you understand exactly what happened and when:
docker events --since "1h" 2024-01-15T10:20:00 container start (name=webapp, image=myapp:1.0) 2024-01-15T10:20:01 container die (name=webapp, exitCode=137) 2024-01-15T10:20:02 container start (name=webapp, image=myapp:1.0) exitCode=137 means killed by SIGKILL (out of memory or manually killed) exitCode=1 means the application itself crashed exitCode=0 means normal exit
Common Exit Codes
Exit Code 0 → Normal exit, task completed successfully Exit Code 1 → Application error (check logs) Exit Code 125 → Docker command itself failed Exit Code 126 → Command found but not executable Exit Code 127 → Command not found (check CMD in Dockerfile) Exit Code 137 → Killed by SIGKILL (OOM or docker kill) Exit Code 143 → Killed by SIGTERM (docker stop)
