Phase 7: Cosmos deployment

- Dockerfile with a check target (typecheck and tests) and one image per
  service on a pinned Node 22.20 Alpine base, each with only its own
  production dependencies and a health check.
- deploy/compose.yaml: gk-content, gk-admin and gk-site on homelab_network
  with no host ports, read-only root filesystems, no capabilities, the vault's
  Site folder mounted into the content service, and backup.dump=sqlite on it.
- deploy/deploy.sh builds and checks the commit, restarts the stack, and goes
  back to the last good tag if it doesn't come up healthy; rollback.sh swaps
  tags. .gitea/workflows/deploy.yml runs it on a host runner on Cosmos.
- docs/deploy.md runbook (settings, runner, mirror, NPM hosts, Turnstile,
  Healthchecks, backups, cutover) and the stack's inventory note in vault-kit.
- Site: trusts X-Forwarded-Host/Proto for gregkilmer.com hosts so form posts
  pass Astro's origin check behind the proxy; rate limits read
  CF-Connecting-IP; site URL set for absolute links.
- Content service: the held-change webhook carries a Discord-ready message;
  .env.example lists the core settings.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
This commit is contained in:
Claude
2026-10-12 00:43:03 +00:00
parent f9a8fb1acd
commit 754c6482be
17 changed files with 472 additions and 5 deletions
+1 -1
View File
@@ -120,7 +120,7 @@ move or write a raw file.
| `CONTENT_TOKENS` | none | `role:token` pairs, comma separated. Roles: reader, agent, editor, admin, intake. Tokens are 24 characters or more. |
| `ALLOWED_EMAILS` | none | Addresses an agent may add without a hold. |
| `HEALTHCHECK_URL` | none | Pinged after every full scan. |
| `NOTIFY_WEBHOOK_URL` | none | Receives `{ event: "held", held }` when a change is held. |
| `NOTIFY_WEBHOOK_URL` | none | Receives `{ content, event: "held", held }` when a change is held. `content` is a one-line message, so a Discord webhook URL works as is. |
| `SCAN_MINUTES` | `5` | Full scan interval, on top of the file watch. |
| `SUBMISSION_MAX_MB` | `10` | Largest attachment a form submission may carry. |
| `SYNC_JOBS` | none | Public sync jobs to run, comma separated: `archidekt`, `bgg`, `covers`. See [Sync jobs](#sync-jobs). |