Skip to content

fix(ops): reclaim disk at deploy-start to prevent ENOSPC (#368)#369

Merged
michaelrobertsutton merged 1 commit into
mainfrom
fix/deploy-disk-reclaim-368
Jun 29, 2026
Merged

fix(ops): reclaim disk at deploy-start to prevent ENOSPC (#368)#369
michaelrobertsutton merged 1 commit into
mainfrom
fix/deploy-disk-reclaim-368

Conversation

@michaelrobertsutton

Copy link
Copy Markdown
Collaborator

Summary

  • Every deploy accumulates dangling images (from pull re-publishing :latest) and BuildKit cache (from up --build) with no cleanup, which exhausted the 30 GB root volume and broke a deploy on ENOSPC
  • Adds a self-healing disk reclaim block (step 1.5) at the very start of the full deploy path — before secret-fetch and before all docker consumers — so each deploy frees space before it consumes it
  • docker image prune -f removes dangling images; docker builder prune -f --keep-storage 5GB bounds build cache to ~5 GB warm; warn-and-continue on failure so a broken flag is visible in CloudWatch without blocking a deploy

Related issue

Closes #368

Type of change

  • Infrastructure / CI/CD

Checklist

  • Tests added or updated (N/A — shell-only change, no Python modified)
  • docs/ updated (N/A — no architecture or API change)
  • No new ADRs needed, OR I've added an entry to docs/decisions.md
  • Security implications considered — no set -x, no secret references in new lines; prune commands touch only dangling images and build cache, never named volumes (HAPI H2, Postgres, Caddy) or running containers

Test plan

  • Lint (ruff check + format) — clean
  • Unit suite (pytest --ignore=tests/integration) — passed
  • Script Security Lint (set -x grep) — clean
  • Bash syntax (bash -n scripts/deploy-prod.sh) — clean
  • CI-equivalent integration suite (./scripts/run-integration-tests.sh --ignore=...) — passed
  • Post-merge (first deploy): watch /leonard/deploy CloudWatch log group for [+] Reclaiming disk before deploy... line, confirm no [!] WARNING: docker ... prune failed line, and verify df -h / output shows freed space vs pre-deploy baseline. Deploy success alone is not sufficient — the reclaim must have actually run. (AWS_PROFILE=leonard)

Every deploy's `pull` orphans the previous :latest images and `up --build`
adds BuildKit cache layers, with no cleanup step — this exhausted the 30 GB
root volume and broke a deploy on ENOSPC. Add a self-healing reclaim block
(step 1.5) that runs before secret-fetch and before all docker consumers:
`docker image prune -f` removes dangling images; `docker builder prune -f
--keep-storage 5GB` bounds build cache to ~5 GB warm. Placed before
step 2 so disk is freed before mktemp too (a near-full volume could fail at
secret-fetch before any later cleanup). Skipped in --post-db-restart mode.
Warn-and-continue on prune failure so a broken flag is visible in CloudWatch
without blocking an otherwise-healthy deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SAwscVmeHmEgU457HJzjNY
@michaelrobertsutton michaelrobertsutton merged commit a5f5b1b into main Jun 29, 2026
6 checks passed
@michaelrobertsutton michaelrobertsutton deleted the fix/deploy-disk-reclaim-368 branch June 29, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ops: schedule weekly Docker prune on EC2 to prevent disk exhaustion

1 participant