Preventing Disk Space Woes on a Home NAS by Configuring Logrotate for Docker Container Logs

Why Docker logs can eat a NAS

A home NAS is usually a single‑disk or a small RAID array.
When you run several containers—media servers, databases, CI runners—each one writes a JSON log file under /var/lib/docker/containers/<id>/<id>-json.log.
If you leave the default json-file driver untouched, those files grow indefinitely.
On a 1 TB NAS, a handful of containers can fill the drive in weeks, forcing you to delete data or upgrade hardware.

The solution is two‑fold:

  1. Tell Docker to stop writing forever – use max‑size and max‑file options.
  2. Let the system clean up old logs – configure logrotate to compress, delete, and rotate the files.

Below is a step‑by‑step guide that works on any recent distribution (Debian, Ubuntu, Arch, Fedora, etc.) and keeps your NAS from running out of space.

Docker’s built‑in size limits

Docker can limit the size of each log file and the number of rotated files it keeps.
Add the options when you create or run a container:

docker run -d \
  --log-driver=json-file \
  --log-opt max-size=10m \
  --log-opt max-file=5 \
  --name=media-server \
  myimage
  • max-size=10m – each log file is capped at 10 MiB.
  • max-file=5 – Docker keeps at most five rotated files per container.

These settings are the first line of defense. They prevent a single container from filling the disk, but they don’t delete old logs after the rotation limit is hit. That’s where logrotate comes in.

Logrotate configuration

Create a dedicated logrotate file for Docker logs:

sudo nano /etc/logrotate.d/docker-containers

Add the following:

/var/lib/docker/containers/*/*.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root root
    sharedscripts
    postrotate
        # Docker writes to a file descriptor; we need to signal it to reopen logs
        if /usr/bin/docker info > /dev/null 2>&1; then
            /usr/bin/docker logs --details > /dev/null 2>&1
        fi
    endscript
}

Explanation of key directives

Directive Meaning Trade‑off
daily Rotate every day Keeps logs fresh; may produce many small files
rotate 7 Keep 7 rotated copies 7 days of logs; adjust for storage
compress Gzip old logs Saves space; CPU cost on rotation
delaycompress Compress only after the next rotation Avoids compressing the most recent file
missingok Ignore missing files Prevents errors when a container is removed
notifempty Skip empty logs Reduces noise
create 0640 root root Set permissions on new log Ensures only root can read/write
sharedscripts Run postrotate only once per file set Avoids duplicate Docker restarts
postrotate … endscript Signal Docker to reopen logs Keeps Docker happy after rotation

Why the postrotate block matters

Docker keeps a file descriptor open to the current log. When logrotate renames the file, Docker keeps writing to the old, renamed file. The postrotate script tells Docker to reopen its log file, so the container starts writing to the new file immediately. Without it, you’d end up with orphaned log files that keep growing.

Applying the limits to existing containers

If you’ve already launched containers without max-size/max-file, you can retro‑apply the settings by updating the daemon configuration:

sudo nano /etc/docker/daemon.json

Add or edit the log-opts section:

{
  "log-driver": "json-file",
  "log-opts": {
    "max-size": "10m",
    "max-file": "5"
  }
}

Then restart Docker:

sudo systemctl restart docker

Existing containers will now honor the limits. New containers will inherit the defaults automatically.

Testing the rotation

A quick sanity check:

  1. Generate a lot of logs
    docker exec -d media-server sh -c "while true; do echo $(date) >> /var/log/media.log; sleep 1; done"
    
  2. Wait a few minutes – the log file should grow until it hits 10 MiB, then a new file appears.
  3. Check logrotate – run sudo logrotate -f /etc/logrotate.d/docker-containers and look at /var/lib/docker/containers/.../*.log. You should see the old files compressed and only a handful remaining.

If everything looks good, you’re set. Your NAS will no longer be threatened by runaway Docker logs.


This setup is a staple in my own home lab. I’ve seen this go wrong when people forget the postrotate step and end up with a mountain of orphaned logs. In practice, the combination of Docker’s built‑in limits and a tidy logrotate rule keeps the disk usage predictable and the system stable.


See also