Context
Production for reportshq.org: Hetzner via ts-cloud, push-to-deploy from GitHub Actions, DNS at Porkbun. loghq is the working reference (config/cloud.ts with provider: 'hetzner', mode: 'server'; .github/workflows/deploy.yml with branch-to-env mapping; note loghq's DEPLOY.md still describes an older AWS path and is stale - do not copy it).
CI is the only clean release path: buddy deploy tars the working directory, not the commit, so a laptop deploy ships whatever is checked out. Deploys run from CI, gated on green lint/typecheck/test, with concurrency queuing (cancel-in-progress: false).
Scope
config/cloud.ts:provider: 'hetzner',mode: 'server',project.slug: 'reportshq'(already set in #2 - verify), sites forreportshq.org+wwwredirect; decide dedicated box vsattachToan existing one and document the choice (a dedicated box avoids the shared-box port/slug hazards; if attaching instead, pick ports fromss -lntpon the box, never from config files of other tenants).- Production database: Postgres on the box (loghq's prod posture) with backups (
ts-backupsfrom~/Code/Librariesif it fits; otherwise a documented pg_dump timer) - an analytics product must not lose the event stream. .github/workflows/deploy.yml: branch-to-env (main-> production), needs green CI, secrets:HCLOUD_TOKEN(needed even when attaching - server resolution goes through the Hetzner API), dedicatedDEPLOY_SSH_KEY(public half derived in-job withssh-keygen -y; never reuse another tenant's key),DOTENV_PRIVATE_KEY_PRODUCTION,APP_KEY, Porkbun keys. Post-deploy check: fail the job unless every site answers 200 - deploy exiting 0 does not mean the site works.- Encrypted
.env.productionviabuddy env:encrypt; verify the release actually loads production env (a known framework foot-gun had a release loading.env.developmentand baking ciphertext into URLs - test for a saneAPP_URLin rendered output post-deploy). - DNS at Porkbun for
reportshq.org: A (+ AAAA only if the box serves IPv6; never AAAA a mail host),www, and mail records if transactional mail runs through the family mail server - schedule/invite emails (#15, #4) need working outbound mail + SPF/DKIM before launch; verify withbuddy email:*/buddy dnstooling. - TLS via the rpx path ts-cloud emits (per-site cert renew units exist and are enabled - audit
rpx-cert-renew-reportshq.*after first deploy). - Staging:
stagebranch -> a staging env or subdomain, same pipeline. - Runbook
docs/deploy.md: secrets inventory, how to roll back (ts-cloud atomic releases + health gate keep the previous release on failure), how to verify.
Acceptance
- Merge to
maindeploys automatically;https://reportshq.orgserves with valid TLS and correctAPP_URL; a deliberately red test blocks the deploy; rollback procedure exercised once.
Depends on #2. Part of #1 (M7 Launch). Ground rules: see #1.