Practical guide: how to reduce Docker container log disk usage on a VPS with rotation, compression and retention without losing traceability
By Kevin Marcondes · Published on · 8 min read
How to reduce Docker container log disk usage on a VPS with rotation, compression and retention without losing traceability? Here you get a quick diagnosis, safe configurations and how to validate everything. The focus is limiting growth, compressing efficiently and keeping trails for audit and debugging without surprises.
The problem: container logs filling the VPS disk
JSON logs can grow unchecked under /var/lib/docker/containers. On VPSes with small disks, just a few hours with DEBUG verbosity is enough to exhaust space and bring services down. The good news: you can limit size, compress and retain what's important without sacrificing investigation capability.
Before making changes, ensure basic filesystem monitoring and alerts are in place. If you don't have that yet, see a baseline using Prometheus and Grafana with Docker in how to set up Prometheus & Grafana with Docker Compose.
Main causes and how to diagnose current volume
In most cases, the default json-file driver writes stdout/stderr without rotation configured. Verbose apps, high log levels and retry loops make the volume skyrocket.
Run a quick diagnosis to map who is using space and where to act first:
- json-file driver without limits (max-size/max-file).
- Applications with DEBUG/TRACE enabled in production.
- Failures with retry loops generating duplicate logs.
- Lack of centralization and external retention outside the VPS.
# Espaço do filesystem
df -h /
# Maiores arquivos de log por container
sudo du -h /var/lib/docker/containers/*/*-json.log | sort -h | tail -n 20
# Uso de espaço por imagens/containers/volumes
docker system df
# Tamanho total de logs por container (agrupado)
sudo find /var/lib/docker/containers -name "*-json.log" -printf '%s %p\n' | awk '{print $1, $2}' | sort -n | tail -n 20
Safe strategy: balanced rotation, compression and retention
For those asking how to reduce Docker container log disk usage on a VPS with rotation, compression and retention without losing traceability, a layered approach works best.
The goal is to limit growth, reduce disk cost and preserve audit trails that are useful. Combine local policies with external retention when needed.
- Rotation and retention on Docker itself (by size and number of files).
- Compression of already-rotated files to save real space.
- Retention policies aligned with your team's audit requirements.
- Optional: centralization (e.g. Fluentd/Elasticsearch or Loki) for search and long-term retention. See centralized logging with Fluentd + Elasticsearch.
Implementation with json-file: native rotation and retention
Define global limits in the Docker daemon for the json-file driver. This controls maximum size per file and the number of rotated files per container. Tune values according to your traffic profile.
After saving, reload Docker. In Compose you can also set logging.driver and logging.options per service if you need exceptions.
- File: /etc/docker/daemon.json
- Reload: sudo systemctl reload docker (or restart if necessary).
- In Compose: logging: driver: "json-file" with equivalent options.
{
"log-driver": "json-file",
"log-opts": {
"max-size": "50m",
"max-file": "5"
}
}
Automatic compression of rotated files (real space savings)
Docker does not compress rotated files. To save space, automate compression with a script and a systemd timer. The rule below compresses files starting at .2, keeping the most recent (.1) for quick inspection.
Warning: do not use logrotate to rotate these files again. Here we only compress files that Docker already rotated.
# /usr/local/bin/compress-docker-logs.sh
set -euo pipefail
# Comprime logs já rotacionados (do .2 em diante) maiores que 1MB
find /var/lib/docker/containers -type f \
-regex ".*\\-json\\.log\\.[2-9][0-9]*$" -size +1M -print0 | xargs -0 -r gzip -9
# Unidade systemd: /etc/systemd/system/compress-docker-logs.service
[Unit]
Description=Compress rotated Docker JSON logs
[Service]
Type=oneshot
ExecStart=/usr/local/bin/compress-docker-logs.sh
# Timer: /etc/systemd/system/compress-docker-logs.timer
[Unit]
Description=Run Docker logs compression periodically
[Timer]
OnCalendar=hourly
Persistent=true
[Install]
WantedBy=timers.target
# Ativar
sudo systemctl daemon-reload
sudo systemctl enable --now compress-docker-logs.timer
Alternatives: local driver, journald or centralization
Depending on your scenario, other options may further reduce disk usage or improve querying. Compare approaches quickly before deciding. For long retention and complex searches, prioritize moving logs off the VPS to a centralized stack.
| Option | Rotation/Retention | Compression | Pros | Cons/Notes |
|---|---|---|---|---|
| json-file (with max-size/max-file) | Easy, by size/number | Via external script | Simplicity, easy onramp | Large JSON files; separate compression |
| local (Docker driver) | By size/number | N/A (binary format) | More space-efficient than JSON | Less readable without docker CLI |
| journald (driver) | By journald policy | Internal compression | Integration with journalctl | Depends on system-wide journald config |
| Centralization (Fluentd/Elasticsearch or Loki) | In the central stack | In the central stack | Search and long retention off the VPS | More components; requires dedicated operation |
Ensuring traceability when limiting and compressing logs
Reducing disk usage must not break investigations. Preserve the essentials to reconstruct events and correlate requests. In audited environments, set a minimum local retention window and transfer history to a centralized logging stack.
- Structured logs (JSON) with timestamps in UTC and explicit log level.
- Correlation ID on every request and propagated across services.
- Include service, version/tag and container_name in logs.
- Avoid DEBUG in production; adopt INFO and well-categorized WARN/ERROR.
- Disk usage alerts and anomalous log growth monitoring in the VPS security checklist.
Verification and troubleshooting common issues
After applying policies, validate that rotation and compression are active and that containers use the intended driver. If something fails, check the points below before reverting.
If your VPS is already critical, free space carefully. Back up anything you must keep before removing files. Also see a snapshot and incremental backup strategy in LVM snapshots + Restic to S3.
This checklist completes the cycle on how to reduce Docker container log disk usage on a VPS with rotation, compression and retention while keeping traceability.
- Old containers may keep their own logging settings; recreate them.
- Compose can override daemon.json; align options.
- copytruncate in logrotate can lose records; prefer Docker's native rotation.
- If no .1 files appear, rotation didn't occur: review max-size.
- Avoid compressing .1 to allow quick inspection of recent incidents.
# Conferir driver e opções de logging de um container
CONTAINER=myapp
docker inspect -f '{{.HostConfig.LogConfig.Type}} {{json .HostConfig.LogConfig.Config}}' "$CONTAINER"
# Ver rotacionados e compactados
ls -lh /var/lib/docker/containers/*/*-json.log*
# Forçar alguns logs e observar rotação
docker logs -f "$CONTAINER" & sleep 2; pkill -f "docker logs -f"
Frequently asked questions
What values should I use for Docker's max-size and max-file?
It depends on log volume and disk size. Start with a moderate per-file size and a small number of rotated files. Monitor for a week and adjust. The important part is keeping filesystem headroom and not losing relevant events.
Can I delete *-json.log.1, .2, etc. manually?
You can, but do so carefully and preferably after confirming rotation and compression are working. If deleting manually, remove only rotated files (.1, .2...), never the active file. Keep backups of anything required for audits.
Is logrotate required for compression?
No. You can use a script with a systemd timer to compress only Docker-rotated files, avoiding conflicts. logrotate is useful when it performs rotation itself, but with Docker it's better to let the driver handle rotation and compress afterwards.
Does switching to the local driver help save space?
In many cases, yes. The local driver stores logs in a more compact binary format than JSON and supports rotation by size/number. Test in a staging environment, validate tools for reading logs and monitor CPU and I/O.
Will these policies affect container performance?
Generally the impact is small. Very small sizes may cause frequent rotations and more I/O. gzip -9 compression is CPU-intensive; run it via a timer and avoid peak hours. Monitor CPU, disk and latency metrics after enabling policies.
How do I keep traceability after compression?
Use structured logs with precise timestamps and correlation IDs. Keep at least one rotated, uncompressed file (.1) for quick inspection. For older investigations, store and query logs in a centralized solution outside the VPS.
Want to reduce log disk usage without losing traceability?
If you need to adapt rotation, compression and retention policies to your Docker environment, let's discuss your context and build a safe plan.
Talk about my Docker environmentSee also
- Intermittent 502 Bad Gateway in Docker Compose with Nginx & PHP‑FPM: how to diagnose and fix timeouts and connection overloads
- How to diagnose and capture packets for intermittent network issues between Docker containers on Debian
- How to detect and fix duplicate SKU inconsistencies between WooCommerce and your ERP without losing orders
- How to reduce build time and avoid duplicate artifacts in CI for large PHP monoliths