Deploy failed with VM disk full — git pull could not write objects; prune ran too late to prevent it #129

Closed
opened 2026-09-13 12:27:13 -04:00 by logan · 0 comments
Owner

Deploy of PR #126 (2026-09-12) failed instantly: git pull origin main on the VM died with fatal: unable to write loose object file: No space left on device / fatal: unpack-objects failed. The rollback path never ran because the failure happened before PREV_TAG was even captured — prod was left on the previous good build, not broken, but no further deploy (including the pending chatter-classifier PR) could land until this cleared.

Root cause: docker image prune -f (dangling-only) only ran AFTER a successful docker compose pull, and only ran -af (all-unused) as a retry-on-pull-failure. A run that fails earlier than that — like this one, at git pull — never reaches either prune. Every deploy pushes 3 freshly SHA-tagged images that nothing else ever removes; docker system df on the VM showed 100 local images, 4 active, 23.76GB reclaimable (96 unreferenced tagged images) — the disk was 29G/29G (100%) full.

Manual fix applied same day: docker image prune -af on the VM, reclaimed 23.76GB, df -h / back to 23% used. Re-ran the stuck deploy via the Gitea API (POST .../actions/runs/{id}/rerun) rather than a new commit.

Durable fix (this PR): move an unconditional docker image prune -af to the very start of the deploy's SSH block, before git pull — so a full disk can never block the pull in the first place — and change the post-up -d prune from -f to -af so stale SHA-tagged images from past deploys don't re-accumulate between now and the next incident. Both prunes are safe by construction: docker image prune -a never removes an image a running container references, so nothing currently serving traffic can be pruned mid-deploy.

Deploy of PR #126 (2026-09-12) failed instantly: `git pull origin main` on the VM died with `fatal: unable to write loose object file: No space left on device` / `fatal: unpack-objects failed`. The rollback path never ran because the failure happened before `PREV_TAG` was even captured — prod was left on the previous good build, not broken, but no further deploy (including the pending chatter-classifier PR) could land until this cleared. Root cause: `docker image prune -f` (dangling-only) only ran AFTER a successful `docker compose pull`, and only ran `-af` (all-unused) as a retry-on-pull-failure. A run that fails earlier than that — like this one, at `git pull` — never reaches either prune. Every deploy pushes 3 freshly SHA-tagged images that nothing else ever removes; `docker system df` on the VM showed 100 local images, 4 active, 23.76GB reclaimable (96 unreferenced tagged images) — the disk was 29G/29G (100%) full. Manual fix applied same day: `docker image prune -af` on the VM, reclaimed 23.76GB, `df -h /` back to 23% used. Re-ran the stuck deploy via the Gitea API (`POST .../actions/runs/{id}/rerun`) rather than a new commit. Durable fix (this PR): move an unconditional `docker image prune -af` to the very start of the deploy's SSH block, before `git pull` — so a full disk can never block the pull in the first place — and change the post-`up -d` prune from `-f` to `-af` so stale SHA-tagged images from past deploys don't re-accumulate between now and the next incident. Both prunes are safe by construction: `docker image prune -a` never removes an image a running container references, so nothing currently serving traffic can be pruned mid-deploy.
logan closed this issue 2026-09-13 12:28:08 -04:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: logan/server-26#129