Container Logging: Docker and Kubernetes Log Management
Docker log drivers, docker logs command, Kubernetes pod logs, centralized log collection (Loki, ELK Stack), log rotation, and production log management best practices.
Table of Contents
Container Logging: Docker and Kubernetes Log Management
Logging in container environments differs from traditional server logging. Since containers are ephemeral, collecting logs centrally outside the container is critical. This guide covers Docker and Kubernetes log management, centralized log collection solutions, and production best practices.
Docker Logging Basics
The docker logs Command
# View container logs
docker logs CONTAINER_NAME
# View last N lines
docker logs --tail 100 CONTAINER_NAME
# Live log streaming
docker logs -f CONTAINER_NAME
# View with timestamps
docker logs -t CONTAINER_NAME
# From a specific time
docker logs --since 2024-01-01T00:00:00 CONTAINER_NAME
docker logs --since 1h CONTAINER_NAME # Last 1 hour
# Specific time range
docker logs --since 2h --until 1h CONTAINER_NAME
# Live + timestamps
docker logs -f -t CONTAINER_NAME
Docker Log Drivers
Docker supports different log drivers:
# Check current log driver
docker info | grep 'Logging Driver'
# View container log driver
docker inspect CONTAINER_NAME | grep LogConfig -A 5
Log Driver Configuration
// /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3",
"compress": "true"
}
}
# Restart Docker daemon
systemctl restart docker
Log Driver at Container Start
# json-file with log rotation
docker run -d \
--name myapp \
--log-driver json-file \
--log-opt max-size=10m \
--log-opt max-file=3 \
myapp:latest
# Forward to syslog
docker run -d \
--name myapp \
--log-driver syslog \
--log-opt syslog-address=udp://localhost:514 \
myapp:latest
# Disable logging (performance critical)
docker run -d \
--name myapp \
--log-driver none \
myapp:latest
Log Configuration with Docker Compose
# docker-compose.yml
version: '3.8'
services:
app:
image: myapp:latest
logging:
driver: json-file
options:
max-size: "10m"
max-file: "5"
compress: "true"
labels: "app,environment"
labels:
- "app=myapp"
- "environment=production"
nginx:
image: nginx:latest
logging:
driver: json-file
options:
max-size: "5m"
max-file: "3"
Kubernetes Pod Logs
# View pod logs
kubectl logs POD_NAME
# Specific container logs (multi-container pod)
kubectl logs POD_NAME -c CONTAINER_NAME
# Live log streaming
kubectl logs -f POD_NAME
# Last N lines
kubectl logs --tail=100 POD_NAME
# From a specific time
kubectl logs --since=1h POD_NAME
# Previous container logs (after crash)
kubectl logs --previous POD_NAME
# Logs from all pods in a deployment
kubectl logs -l app=myapp --all-containers
# With namespace
kubectl logs -n production POD_NAME
Centralized Log Collection: Loki + Grafana
Loki Stack with Docker Compose
# loki-stack.yml
version: '3.8'
services:
loki:
image: grafana/loki:latest
ports:
- "3100:3100"
volumes:
- loki-data:/loki
command: -config.file=/etc/loki/local-config.yaml
promtail:
image: grafana/promtail:latest
volumes:
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
- ./promtail-config.yml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_SECURITY_ADMIN_PASSWORD=StrongPass123!
volumes:
- grafana-data:/var/lib/grafana
volumes:
loki-data:
grafana-data:
Promtail Configuration
# promtail-config.yml
server:
http_listen_port: 9080
grpc_listen_port: 0
positions:
filename: /tmp/positions.yaml
clients:
- url: http://loki:3100/loki/api/v1/push
scrape_configs:
- job_name: docker
docker_sd_configs:
- host: unix:///var/run/docker.sock
refresh_interval: 5s
relabel_configs:
- source_labels: ['__meta_docker_container_name']
regex: '/(.*?)'
target_label: 'container'
- source_labels: ['__meta_docker_container_log_stream']
target_label: 'logstream'
Loki with Docker Log Driver
# Install Loki Docker plugin
docker plugin install grafana/loki-docker-driver:latest \
--alias loki \
--grant-all-permissions
# Send logs to Loki at container start
docker run -d \
--name myapp \
--log-driver loki \
--log-opt loki-url="http://localhost:3100/loki/api/v1/push" \
--log-opt loki-batch-size=400 \
myapp:latest
// /etc/docker/daemon.json — Loki for all containers
{
"log-driver": "loki",
"log-opts": {
"loki-url": "http://localhost:3100/loki/api/v1/push",
"loki-batch-size": "400",
"loki-retries": "3",
"loki-max-backoff": "800ms",
"loki-timeout": "1s"
}
}
Log Rotation and Disk Management
# Check Docker log file sizes
du -sh /var/lib/docker/containers/*/*-json.log
# Clear all container logs (careful!)
truncate -s 0 /var/lib/docker/containers/*/*-json.log
# Clear specific container log
truncate -s 0 $(docker inspect --format='{{.LogPath}}' CONTAINER_NAME)
# Automatic rotation with logrotate
cat > /etc/logrotate.d/docker-containers << 'EOF'
/var/lib/docker/containers/*/*.log {
rotate 7
daily
compress
size=10M
missingok
delaycompress
copytruncate
}
EOF
Structured Logging (JSON)
// Node.js — JSON logging with Winston
const winston = require('winston');
const logger = winston.createLogger({
level: 'info',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.errors({ stack: true }),
winston.format.json()
),
transports: [
new winston.transports.Console()
]
});
// Usage
logger.info('User login', {
userId: 123,
action: 'login',
ip: '192.168.1.1'
});
logger.error('Database error', {
error: err.message,
query: 'SELECT * FROM users'
});
Conclusion
Effective container logging is essential for troubleshooting and monitoring system health in production environments. Prevent disk overflow with Docker log rotation, set up centralized log collection with Loki or ELK Stack, and simplify log analysis with structured JSON logs. With these configurations on REXE servers, you can manage your container infrastructure with full visibility.
Related Articles
K3s Kubernetes Setup: Lightweight Container Orchestration
Single and multi-node Kubernetes cluster setup with K3s, kubectl usage, creating deployments and services, application management with Helm. Kubernetes guide for VPS environments.
Docker Volume and Network Management: Persistent Storage and Network Configuration
Docker volume types (named, bind mount, tmpfs), volume management, Docker network modes (bridge, host, overlay), creating custom networks and container communication. Comprehensive guide.
Docker Security: Hardening Your Container Environment
Docker security best practices: non-root user, read-only filesystem, seccomp profiles, image scanning, Docker socket security, network isolation, and secrets management.