Skip to main content

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

  1. Inspecting Containers
  2. Accessing Container Logs
  3. Debugging Containers with Interactive Shells
  4. Using Docker Events and Stats
  5. Configuring and Managing Docker Logs
  6. Common Mistakes and Pitfalls
  7. Summary
  8. 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/bash

    This 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 events

    Useful 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

  1. 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
  2. True or False: The docker logs command will always show application logs, even if the application writes logs to files inside the container.

    • Answer: False
  3. What flag would you use with docker run to 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
  4. 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
  5. 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).