also looking at this
feat(deploy): make host cleanup a property of the host, not of deploying
#196
6 files
+374
-21
| @@ -96,6 +96,50 @@ cloud release:pin <release-id> --remove | ||
| 96 | 96 | |
| 97 | 97 | Retention candidates never include active, activating, awaiting-approval, pinned, or currently referenced rollback releases. The store keeps a configurable minimum per resource and exposes candidates rather than deleting provider artifacts implicitly. |
| 98 | 98 | |
| 99 | ## Host disk retention | |
| 100 | ||
| 101 | Release history is one thing a box accumulates; deploy machinery is another. Compute hosts also carry a content-addressed upload cache, staging tarballs, package caches, container images, and journals. These are reclaimed by a cleanup pass that runs **on a systemd timer as well as after each deploy** — a box that stops deploying keeps cleaning itself, and a deploy that fails no longer skips the pass that would have collected its leftovers. | |
| 102 | ||
| 103 | The pass reads root-filesystem usage before it does anything, and behaves differently by band: | |
| 104 | ||
| 105 | | Root usage | Behavior | | |
| 106 | | --- | --- | | |
| 107 | | Below `relaxedBelowPercent` (default 50%) | Reclaims deploy leftovers only. Caches that cost network to rebuild — the Bun download cache, container images, apt — are left alone. | | |
| 108 | | Between the two thresholds | Full pass at the configured windows. | | |
| 109 | | At or above `escalateAtPercent` (default 85%) | Full pass with every configurable window divided by `escalationFactor` (default 4). | | |
| 110 | ||
| 111 | Bounds that exist for correctness rather than retention never move with pressure: an in-flight upload belonging to a concurrent deploy on a shared box survives its hour however full the disk is. | |
| 112 | ||
| 113 | Defaults suit a typical box. A host packing many sites onto one disk is the case worth tuning: | |
| 114 | ||
| 115 | ```ts | |
| 116 | infrastructure: { | |
| 117 | compute: { | |
| 118 | cleanup: { | |
| 119 | // The upload cache mostly pays for itself within a single deploy — one | |
| 120 | // upload, N sites copying it locally seconds later. Keep it short. | |
| 121 | artifactMaxAgeMinutes: 720, | |
| 122 | escalateAtPercent: 80, | |
| 123 | onCalendar: 'daily', | |
| 124 | }, | |
| 125 | }, | |
| 126 | } | |
| 127 | ``` | |
| 128 | ||
| 129 | Components that write timestamped output to paths ts-cloud does not own register their own rules rather than accumulating unattended: | |
| 130 | ||
| 131 | ```ts | |
| 132 | cleanup: { | |
| 133 | rules: [ | |
| 134 | { path: '/root/rpx-backups', pattern: 'cert-backup-*', maxAgeMinutes: 4320, directories: true }, | |
| 135 | ], | |
| 136 | } | |
| 137 | ``` | |
| 138 | ||
| 139 | Each run prints root usage before and after, so the deploy log carries the trend. Set `timer: false` to keep the deploy-time pass and schedule the host's cleanup yourself. | |
| 140 | ||
| 141 | Rollback depth is separate and unchanged: `keepReleases` (default 4) governs how many past releases stay on the box, and cleanup never touches active or rollback releases. | |
| 142 | ||
| 99 | 143 | ## Automation API |
| 100 | 144 | |
| 101 | 145 | The versioned OpenAPI document and TypeScript client expose: |