Debugging and Logging in Docker
Introduction
Debugging and logging are critical skills for any developer or operations engineer working with Docker. Containers can sometimes feel opaque, making it challenging to understand what’s happening inside, especially when things go wrong. In this lesson, you’ll learn how to inspect running containers, access logs, and use various Docker tools and techniques to identify and resolve issues efficiently. You will also explore best practices for managing logs in containerized environments.
Table of Contents
- Inspecting Containers
- Accessing Container Logs
- Debugging Containers with Interactive Shells
- Using Docker Events and Stats
- Configuring and Managing Docker Logs
- Common Mistakes and Pitfalls
- Summary
- Quiz
Inspecting Containers
Docker provides several commands and tools to inspect the state and configuration of containers.
Using docker ps and docker inspect
-
List running containers:
docker ps -
View detailed information on a container:
docker inspect <container_id>This outputs a JSON object containing configuration, state, networking, mounts, and more.
Use Case
If a container is not behaving as expected, docker inspect can reveal environment variables, mount points, or network settings that may be misconfigured.
Accessing Container Logs
Docker uses a logging driver to capture output from containers. By default, logs are written to STDOUT and STDERR.
Using docker logs
-
View logs from a running or stopped container:
docker logs <container_id> -
Follow logs in real-time (like
tail -f):docker logs -f <container_id> -
Display only the last N lines:
docker logs --tail 50 <container_id>
Example
Suppose you have a web server container:
docker run -d --name webserver nginx
docker logs webserver
This will show the access and error logs from the Nginx server.
Use Case
Logs are essential for troubleshooting application errors, crashes, and startup issues.
Debugging Containers with Interactive Shells
Sometimes, you may need to “get inside” a running container to debug issues interactively.
Using docker exec
-
Start a shell inside a running container:
docker exec -it <container_id> /bin/sh
# or, for containers with bash
docker exec -it <container_id> /bin/bashThis opens an interactive shell where you can inspect the filesystem, run diagnostics, or change configuration files.
Example
docker exec -it webserver /bin/bash
Use Case
If a container fails health checks, you can use an interactive shell to check logs, process status, or test network connectivity from within the container.
Using Docker Events and Stats
Monitoring Events
-
Track Docker events (container start, stop, etc.):
docker eventsUseful for real-time monitoring of container lifecycle and errors.
Monitoring Resource Usage
-
Check container resource usage (CPU, memory, I/O):
docker stats <container_id>Or for all containers:
docker stats
Use Case
If a container is being killed unexpectedly, docker stats can reveal if it’s running out of memory or CPU.
Configuring and Managing Docker Logs
By default, Docker uses the json-file logging driver, but you can configure others (e.g., syslog, journald, fluentd, awslogs).
Specifying a Logging Driver
docker run --log-driver=syslog alpine echo "Hello World"
Log Rotation
Logs can grow quickly and fill up disk space. Configure log rotation to prevent this.
Example: Limit log size and files
docker run \
--log-opt max-size=10m \
--log-opt max-file=3 \
nginx
This keeps up to 30MB of logs per container (3 files, 10MB each).
Centralized Log Management
For production environments, consider shipping logs to centralized systems (ELK stack, Fluentd, etc.) using appropriate logging drivers.
Common Mistakes and Pitfalls
- Not configuring log rotation: This can quickly fill up disk space, leading to container or host failures.
- Relying solely on
docker logs: Some applications log to files inside the container, not STDOUT/STDERR. Make sure your app is configured correctly. - Forgetting to check exit codes: Always check the exit code of stopped containers to diagnose failures.
- Overlooking resource constraints: Containers killed due to out-of-memory (OOM) errors may need memory limits adjusted.
Summary
Debugging and logging are vital for maintaining healthy Dockerized applications. Mastering commands like docker ps, docker inspect, docker logs, and docker exec allows you to efficiently diagnose and solve issues. Proper log management—using the right drivers and enabling log rotation—is crucial, especially in production environments. By avoiding common pitfalls and utilizing Docker’s built-in tools, you can keep your containerized applications running smoothly.
Quiz
-
Which command would you use to get a real-time stream of log output from a running container?
- a)
docker inspect - b)
docker logs -f - c)
docker ps - d)
docker exec - Answer: b)
docker logs -f
- a)
-
True or False: The
docker logscommand will always show application logs, even if the application writes logs to files inside the container.- Answer: False
-
What flag would you use with
docker runto limit the log file size to 5 megabytes and keep only 2 log files?- Answer:
--log-opt max-size=5m --log-opt max-file=2
- Answer:
-
Which command allows you to open an interactive shell inside a running container?
- a)
docker shell - b)
docker attach - c)
docker exec -it <container_id> /bin/bash - d)
docker start -i - Answer: c)
docker exec -it <container_id> /bin/bash
- a)
-
Name one reason why a container might be killed unexpectedly that you could diagnose with
docker stats.- Answer: The container is exceeding its memory or CPU limits (e.g., running out of memory and being killed by the OOM killer).