Disk pressure¶
Purpose. Get free space back without losing anything that cannot be rebuilt, and keep the margin that dumps and restores need. Low disk on a box with databases and backups is a capacity incident, not housekeeping. Level. 1 to read. 2 to prune the Docker build cache, and to remove an image proved unreferenced, one by one, under an instruction. 3 for everything else: volumes, data, backups, images still referenced, anything outside Docker. Preconditions. None to read.
What the doctor's disk check says¶
| Free space | Percent used | Result |
|---|---|---|
| below 2 GiB | any | fail |
| below 10 GiB (the installer's minimum) | any | warn, the free space is the reason |
| 10 to 15 GiB | 85 % or more | warn, the percentage with the space near the minimum |
| 15 GiB or more | 85 % or more | ok, with a note ("88 % used, 26.8 GiB free") |
| 10 GiB or more | below 85 % | ok |
The action line says which of the two criteria fired.
Read first, always¶
df -h / "$I" "$BACKUP_DESTINATION" # which file system is short
docker system df -v | sed -n '1,40p' # images, containers, volumes, build cache
du -xh --max-depth=2 "$I" 2>/dev/null | sort -h | tail -15
du -xh --max-depth=1 "$BACKUP_DESTINATION" 2>/dev/null | sort -h
(agent) ihc-ro df (images, which are used by no container, build cache in use or not, volumes); the disk usage of the host itself needs the human.
Sort what you found into three kinds, and say which is which:
| Kind | Example | Rebuildable | Level |
|---|---|---|---|
| Build cache | docker builder du |
yes, at the cost of slower builds | 2 |
| Images with no tag, or used by no container | superseded <slug>-app builds, <none>:<none> |
yes, if its source is known (a commit on main, a public tag) |
2, one by one with the list |
Images still referenced, volumes, app-data/, the restic repository, dumps |
— | no | 3, and usually not at all |
Act¶
docker builder prune -f # build cache only (level 2)
docker image ls --filter dangling=true # show first
docker image rm <id> <id> # only ids from the list shown, never -f
(agent) with ops.agent.allow_write: ihc-ro prune-build-cache (POST /build/prune through its Docker API); image removal is not on its allowlist: it shows the list and the human runs it.
Never by reflex: docker system prune, docker image prune -a, docker volume prune. Each removes things that look unused and are not (a stopped app's image, a volume of a service under a profile that is off).
On macOS with Docker Desktop, freed space stays inside Docker's virtual disk; set a maximum disk image size instead of compacting a running one.
Post-checks¶
df -h again; report the space recovered and from what. Keep a margin of at least twice the largest database dump free on the file system where dumps are written, plus room for one image build. Before any migration, database-migration checks this margin again.
Example¶
On the first box free disk fell to about 14 GiB while dumps and image builds were running: build cache and superseded images had accumulated with every deploy (tens of GiB). Only the build cache and images verified to be referenced by no container were removed; no volume, database or mount was touched; later dumps were written straight to the backup disk. That margin is now a pre-check, not a discovery.