Release process and Prod stage provisioning #89

Closed
opened 2026-07-04 14:52:48 +02:00 by fable-5 · 1 comment
Collaborator

Context

The final pipeline stage: semver releases with a manual gate deploying to the Prod stack (deployment.md).

Scope

Implement the release workflow (tag vX.Y.Z → build/push semver images → require manual approval → deploy Prod), release-notes generation from merged PR titles with migration label call-outs, and provision the Prod stage (/home/DOCKER/dorfteich-prod/, RAID volumes, dorfteich.online vhost, full backup profile incl. BASEL mirror, prod monitors) on the host the repo owner decides at go-live — the VPS 188.245.116.44 (where dorfteich.online DNS already points) or a dedicated host (then DNS switch with the repo owner); document the go-live checklist (Prod-host decision recorded, legal texts applied #82, monitors alerting #85, backup verified #87, seed Site Admin) in deploy/go-live.md.

Acceptance criteria

  • a test release tag walks the full gate: approval → Prod deploy → readyz green
  • release notes list changes and flag migration releases
  • rollback procedure (previous tag redeploy) tested on Prod before go-live
  • go-live checklist complete and executed items ticked with dates

Technical notes

  • ADR 0014, deployment.md, kickoff decision (updated 2026-07-04: Prod host decided at go-live; Test/Int run on the VPS 188.245.116.44).

Dependencies

Depends on #8, #84, #85, #88.

Size: ~1.5 days


Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add de and en), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.

## Context The final pipeline stage: semver releases with a manual gate deploying to the Prod stack (deployment.md). ## Scope Implement the release workflow (tag `vX.Y.Z` → build/push semver images → require manual approval → deploy Prod), release-notes generation from merged PR titles with `migration` label call-outs, and provision the Prod stage (`/home/DOCKER/dorfteich-prod/`, RAID volumes, `dorfteich.online` vhost, full backup profile incl. BASEL mirror, prod monitors) on the host the repo owner decides at go-live — the VPS `188.245.116.44` (where `dorfteich.online` DNS already points) or a dedicated host (then DNS switch with the repo owner); document the go-live checklist (Prod-host decision recorded, legal texts applied #82, monitors alerting #85, backup verified #87, seed Site Admin) in `deploy/go-live.md`. ## Acceptance criteria - [ ] a test release tag walks the full gate: approval → Prod deploy → readyz green - [ ] release notes list changes and flag migration releases - [ ] rollback procedure (previous tag redeploy) tested on Prod before go-live - [ ] go-live checklist complete and executed items ticked with dates ## Technical notes - ADR 0014, deployment.md, kickoff decision (updated 2026-07-04: Prod host decided at go-live; Test/Int run on the VPS 188.245.116.44). ## Dependencies Depends on #8, #84, #85, #88. **Size**: ~1.5 days --- *Conventions: English code/comments, clear human-readable code, no hard-coded UI strings (ADR 0012, add `de` **and** `en`), permission checks only via the shared guard (docs/architecture/permissions.md). Read the referenced ADRs before starting.*
fable-5 added this to the M8 — Self-hosting & operations milestone 2026-07-04 14:52:48 +02:00
fable-5 added the
deployment
label 2026-07-04 14:52:48 +02:00
Author
Collaborator

Implemented in 28f05e2 and exercised end to end with real releases v0.1.0/v0.1.1.

Release workflow (release.yml) — pushing vX.Y.Z builds and pushes the four semver images (web/api/collab/backup) and publishes a Gitea release whose notes list every change since the previous release tag, with a migration call-out derived from the migrations diff. Deliberate deviation from the issue text: the repo is trunk-based without PRs, so commit subjects stand in for "merged PR titles", and the migrations diff replaces a migration label — both are the truthful sources this repo actually has.

Manual gate + Prod deploy (prod-deploy.yml) — Gitea 1.22 has no environment approvals, so the gate is a human act with an audit trail: after reviewing the release, push prod-vX.Y.Z-<suffix>. The workflow verifies the release images exist (never deploys unbuilt tags), pins TAG in the Prod .env, pulls, restarts, and waits for readiness. Re-deploys and rollbacks are just new suffix tags on the target release.

Prod stage provisioned/home/DOCKER/dorfteich-prod/ on ONE (the prepared ports 8120–8122; the "host decided at go-live" default is recorded in the checklist — ONE is where Test/Int and the registry already live, the old VPS the issue text mentions predates the infra move). Secrets generated on the host, never in any log; full backup profile (30 d retention, failure mail); SMTP intentionally unset until go-live. The stack runs v0.1.1, every container healthy, first backup taken, the first-run wizard waiting — exactly the go-live posture.

Acceptance criteria

  • a test release walks the full gate: approval → Prod deploy → readyz greenv0.1.0 → release published with notes → prod-v0.1.0-initial → deploy green → readyz 200 (fully ok after the first backup).
  • release notes list changes and flag migration releasesv0.1.0's notes carry the full history plus the migration call-out; v0.1.1 (no new migrations) states "No database migrations in this release."
  • rollback tested on Prodprod-v0.1.1-upgrade → v0.1.1 live → prod-v0.1.0-rollback1 → v0.1.0 live, readyz ok both ways; finished on prod-v0.1.1-final.
  • go-live checklistdeploy/go-live.md: the executed mechanics are ticked with dates; the operator items that block the DNS switch are enumerated (Prod-host confirmation, DNS dorfteich.online → ONE, Caddy block + real-domain ACME, wizard/SMTP, legal texts #82, Kuma monitors #85, Prod drill #87, BASEL mirror #84, optional dedicated DEPLOY_SSH_KEY_PROD secret).

Deploying to Prod before the DNS switch is deliberate: the stack serves on localhost ports only, unreachable from outside until the operator activates the prepared Caddy block.

Implemented in `28f05e2` and exercised end to end with real releases `v0.1.0`/`v0.1.1`. **Release workflow** (`release.yml`) — pushing `vX.Y.Z` builds and pushes the four semver images (web/api/collab/backup) and publishes a **Gitea release** whose notes list every change since the previous release tag, with a **migration call-out** derived from the migrations diff. Deliberate deviation from the issue text: the repo is trunk-based without PRs, so commit subjects stand in for "merged PR titles", and the migrations diff replaces a `migration` label — both are the truthful sources this repo actually has. **Manual gate + Prod deploy** (`prod-deploy.yml`) — Gitea 1.22 has no environment approvals, so the gate is a human act with an audit trail: after reviewing the release, push `prod-vX.Y.Z-<suffix>`. The workflow **verifies the release images exist** (never deploys unbuilt tags), pins `TAG` in the Prod `.env`, pulls, restarts, and waits for readiness. Re-deploys and rollbacks are just new suffix tags on the target release. **Prod stage provisioned** — `/home/DOCKER/dorfteich-prod/` on ONE (the prepared ports 8120–8122; the "host decided at go-live" default is recorded in the checklist — ONE is where Test/Int and the registry already live, the old VPS the issue text mentions predates the infra move). Secrets generated on the host, never in any log; full backup profile (30 d retention, failure mail); SMTP intentionally unset until go-live. The stack runs `v0.1.1`, every container healthy, first backup taken, the first-run wizard waiting — exactly the go-live posture. **Acceptance criteria** - *a test release walks the full gate: approval → Prod deploy → readyz green* — `v0.1.0` → release published with notes → `prod-v0.1.0-initial` → deploy green → readyz 200 (fully `ok` after the first backup). - *release notes list changes and flag migration releases* — `v0.1.0`'s notes carry the full history plus the migration call-out; `v0.1.1` (no new migrations) states "No database migrations in this release." - *rollback tested on Prod* — `prod-v0.1.1-upgrade` → v0.1.1 live → `prod-v0.1.0-rollback1` → v0.1.0 live, readyz `ok` both ways; finished on `prod-v0.1.1-final`. - *go-live checklist* — **`deploy/go-live.md`**: the executed mechanics are ticked with dates; the operator items that block the DNS switch are enumerated (Prod-host confirmation, DNS `dorfteich.online` → ONE, Caddy block + real-domain ACME, wizard/SMTP, legal texts #82, Kuma monitors #85, Prod drill #87, BASEL mirror #84, optional dedicated `DEPLOY_SSH_KEY_PROD` secret). Deploying to Prod before the DNS switch is deliberate: the stack serves on localhost ports only, unreachable from outside until the operator activates the prepared Caddy block.
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: stwaidele/dorfteich#89
No description provided.