Stage 4 · Provision
Running & Networking Containers
Logs & exec
Debug containers with docker logs, docker exec, docker inspect, exit codes, and process signals.
Viewing Logs
docker logs reads the stdout and stderr output of a container's main process. This is the primary way to see what your application is doing. Logs are available even for stopped containers, as long as the container has not been removed.
# View all logs
docker logs mycontainer
# Follow logs in real time (like tail -f)
docker logs -f mycontainer
# Show last N lines
docker logs --tail 100 mycontainer
# Show logs since a timestamp
docker logs --since 2025-01-15T10:00:00 mycontainer
# Show logs until a timestamp
docker logs --until 2025-01-15T12:00:00 mycontainer
# Show timestamps
docker logs -t mycontainerdocker logs reads from the container's log driver. By default, Docker captures stdout and stderr. If your application logs to a file instead of stdout, docker logs will not capture it.
Log Drivers
Docker supports multiple log drivers that determine where container logs are stored. The default json-file driver stores logs as JSON on the host. Other drivers send logs to centralized logging systems.
| Driver | Description | Use Case |
|---|---|---|
| json-file | Logs as JSON on host disk | Default, simple setups |
| local | Optimized json-file with compression | Local development |
| syslog | Send to syslog server | Syslog infrastructure |
| journald | Send to systemd journal | Systemd-based hosts |
| fluentd | Send to Fluentd | Centralized logging |
Exec Into Containers
docker exec starts a new process inside a running container. This is essential for debugging — you can open a shell, inspect files, check configurations, and run diagnostic commands without affecting the main process.
# Open an interactive shell
docker exec -it mycontainer sh
# Run a single command
docker exec mycontainer cat /etc/nginx/nginx.conf
# Run as a different user
docker exec -u root mycontainer cat /etc/shadow
# Set environment variables for the exec session
docker exec -e DEBUG=true mycontainer env
# Run in a specific working directory
docker exec -w /app/logs mycontainer ls -ladocker exec creates a new process in the container's namespaces. It does not restart the container or affect the main process. The exec process is independent.
Exit Codes
Exit codes indicate why a container stopped. Understanding exit codes helps you diagnose crashes, configuration errors, and application failures.
| Exit Code | Meaning | Common Cause |
|---|---|---|
| 0 | Success | Normal exit |
| 1 | Application error | Uncaught exception, config error |
| 125 | Docker daemon error | Cannot start container |
| 126 | Command cannot execute | Permission denied on binary |
| 127 | Command not found | Invalid ENTRYPOINT or CMD |
| 137 | SIGKILL | OOM killed or docker kill |
| 139 | SIGSEGV | Segmentation fault |
| 143 | SIGTERM | docker stop or SIGTERM |
# See exit code in docker ps
docker ps -a --format "table {{.Names}} {{.Status}}"
# Inspect specific exit code
docker inspect mycontainer --format '{{.State.ExitCode}}'
# Check if container was OOM killed
docker inspect mycontainer --format '{{.State.OOMKilled}}'
# View exit code in docker inspect
docker inspect mycontainer --format '{{.State.ExitCode}} {{.State.Error}}'Exit code 137 (SIGKILL) often means the container was OOM killed. Check with docker inspect --format '{{.State.OOMKilled}}'. Exit code 143 (SIGTERM) is normal when you run docker stop.
Process Signals
Containers respond to Unix signals. Understanding signal handling is critical for graceful shutdowns. docker stop sends SIGTERM, waits 10 seconds, then sends SIGKILL. Your application should handle SIGTERM for clean shutdown.
# Send SIGTERM (default stop signal)
docker stop mycontainer
# Send SIGKILL immediately (force kill)
docker kill mycontainer
# Send a custom signal
docker kill --signal=SIGHUP mycontainer
# Change the stop signal in Dockerfile
STOPSIGNAL SIGQUITSIGTERM allows graceful shutdown — the application can close connections and save state. SIGKILL terminates immediately without cleanup. Always handle SIGTERM in production applications.
docker inspect
docker inspect returns detailed JSON metadata about any Docker object. It shows network settings, mount points, environment variables, state, configuration, and more. Use --format with Go templates to extract specific fields.
# Full inspect output
docker inspect mycontainer
# Get the container's IP address
docker inspect --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' mycontainer
# Get mount points
docker inspect --format '{{json .Mounts}}' mycontainer | jq
# Get environment variables
docker inspect --format '{{json .Config.Env}}' mycontainer | jq
# Get the restart policy
docker inspect --format '{{.HostConfig.RestartPolicy.Name}}' mycontainerdocker inspect --format uses Go template syntax. {{json .Field}} outputs JSON, which you can pipe to jq for pretty-printing. This is invaluable for scripting and automation.
docker inspect with --format is the most reliable way to extract container metadata in scripts. Unlike parsing docker ps output, inspect returns structured data that does not change with formatting updates.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.