How to make docker evict stuff
Stop docker slowly filling your disk
Docker is a popular local disk cache, masquerading as virtualisation technology.
The problem is that, unlike a real cache, Docker doesn't handle it's own "eviction" - nothing is ever deleted. The means that docker slowly grows to fill your whole disk. When working on a commercial project, (re)building big images over and over this can happen quite quickly: in weeks.
Eviction, of a kind
The best way, as far as I know, to do some eviction is by running
docker system prune --all --force --filter "until=432h"
This "prunes" docker data.
--all- everything, not just "dangling" stuff--force- don't ask for confirmation--filter "until=528h"- older than 22 days (about 3 weeks)--volumes- also anonymous volumes
Why 22 days? It's often a good idea to ensure that periods for things
like cleanup, log retention, etc don't align with human periods
like calendar weeks. Otherwise you find yourself coming in every Monday
morning to find the entire cache has been cleared, or that bugs that happen
at end-of-month don't have the logs from the previous month recorded. Keep
sysadmin periods at n+a_little_bit.
And also note: this isn't real LRU ("least recently used") eviction. Real caches, like memcache, don't evict old stuff, they evict stuff that isn't being used very often, which is different. Unfortunately docker doesn't seem to record access times for it's layers/volumes/whatever so proper LRU is impossible. Instead, you just have to suffer everything occasionally getting deleted.
Automating it
No one wants "just one more thing to remember" so best to set the command to run automatically. Here's how with systemd:
# $HOME/.config/systemd/docker-prune.timer
[Unit]
Description=Prune docker data
[Timer]
OnCalendar=daily
RandomizedDelaySec=1h # ensure it doesn't happen at boot/resume from suspend
Persistent=true
[Install]
WantedBy=timers.target
# $HOME/.config/systemd/docker-prune.timer
[Unit]
Description=Prune unused Docker data
Documentation=https://docs.docker.com/engine/reference/commandline/system_prune/
[Service]
Type=oneshot
ExecStart=/usr/bin/docker system prune --all --force --filter "until=528h"
Then you:
systemctl --user daemon-reload
systemctl --user enable docker-prune