Debugging Docker Containers Like a Pro
Docker. The magical technology that promises to make deployment a breeze—until something goes wrong. Suddenly, your container won’t start, your logs are cryptic, and your perfectly crafted application is refusing to cooperate. Welcome to the world of debugging Docker containers.
Fear not! With the right tools and techniques, you can crack even the most stubborn containerized mysteries. Let’s dive into the art and science of debugging Docker like a pro.
The Debugging Mindset 🧠
Before reaching for commands, let’s talk mindset. Debugging is part detective work, part structured problem-solving. The key? Work methodically:
- Reproduce the issue – Ensure it’s consistent.
- Check the basics – Logs, container status, and exit codes.
- Isolate the problem – Is it your app, the container, or the environment?
- Test hypotheses – Make one change at a time, observe the effects.
- Log and document – Keep track of findings for future reference.
With that in mind, let’s roll up our sleeves and get technical.
Core Debugging Techniques 🔍
1. Inspect Container Logs 📝
First stop: logs. If a container misbehaves, logs will often tell you why.
docker logs <container_id>
Use -f
to follow logs in real-time:
docker logs -f <container_id>
If using Docker Compose:
docker-compose logs -f <service_name>
💡 Pro tip: Structured logging (e.g., JSON logs) makes debugging easier. Tools like Loki + Grafana can centralize and visualize logs for better insights.
2. Check Container Status & Restart Policies 🚦
Sometimes, containers exit without explanation. Find out why:
docker ps -a
Check exit codes:
docker inspect <container_id> --format='{{.State.ExitCode}}'
Common exit codes:
0
– Normal exit1
– Generic error (check logs!)137
– Killed (OOM ordocker stop
)139
– Segmentation fault
Prevent extended periods of downtime caused by recurring crashes by updating the restart policy of a running container:
First, update the container’s restart policy:
docker update --restart=always <container_id>
To confirm the change:
docker inspect --format='{{.HostConfig.RestartPolicy.Name}}' <container_id>
3. Dive into the Running Container 🕵️♂️
When logs aren’t enough, jump into the container shell:
docker exec -it <container_id> sh # For Alpine-based images
For Debian/Ubuntu-based containers:
docker exec -it <container_id> bash
Once inside, explore:
ps aux # Check running processes
netstat -tuln # Check open ports
env # View environment variables
ls -lah # Inspect the filesystem
An alternative to using docker exec
is to use docker attach
to attach your terminal to a running container, so you can view its output or control it, as though the commands were running directly in your terminal.
💡 Pro tip: If a container keeps crashing, run it manually:
docker run -it --entrypoint sh myapp
4. Network Debugging 🌐
Containers sometimes fail due to misconfigured networking. Verify connections:
List networks:
docker network ls
Check which network a container is in:
docker inspect <container_id> | grep -i network
Test connectivity between containers:
docker exec -it <container_id> ping <other_container>
If DNS is failing inside a container:
docker run --rm busybox nslookup google.com
5. Debugging Dockerfile Issues 📦
If a build fails, check the last successful step:
docker build . --progress=plain
Common pitfalls:
- Caching issues – Try
--no-cache
- Missing dependencies – Install them in
RUN
commands - Permissions issues – Use
chmod
on copied files - Wrong
CMD
syntax – EnsureCMD
is an array (["python", "app.py"]
)
6. Volume & File Debugging 📂
If a container isn’t persisting data correctly, check mounted volumes:
docker inspect <container_id> | grep -i mount
Or manually inspect files:
docker run --rm -v myvolume:/data busybox ls /data
7. Memory & CPU Issues 🖥️
If a container is slow or crashes randomly, check resource limits:
docker stats
Limit CPU & memory usage:
docker run --memory=512m --cpus=1 myapp
If an app is OOM-killed:
dmesg | grep -i oom
💡 Pro tip: Use --ulimit
to prevent excessive memory usage:
docker run --ulimit memlock=64M myapp
Missing Debugging Tools 🛠️
Sometimes, container images lack essential debugging tools like tcpdump
, nslookup
, or netstat
. If these are missing, install them using the package manager inside the container:
For Alpine-based images:
apk add tcpdump bind-tools net-tools
For Debian/Ubuntu-based images:
apt update && apt install -y tcpdump dnsutils net-tools
⚠️ Important: Avoid manually modifying running containers. Instead, update the Dockerfile or image, then rebuild and redeploy. This ensures consistency across all instances of the container.
Debugging Like a Pro 🏆
Docker is fantastic—until it isn’t. But armed with the right mindset, techniques, and tools, you can diagnose and fix container issues like a seasoned pro.
Next time your container misbehaves, don’t panic. Logs, inspect, exec, and network tests will almost always reveal the culprit. And when in doubt, rebuild and retry.
Happy debugging! 🐳