docs: ADR-0002 — all owned image builds move off-infra to GHA + ghcr [ci skip]
Viktor asked to evaluate fully external image builders because in-cluster CI builds keep destabilising the homelab (Forgejo OOM under registry-push load, hairpin push timeouts, build IO on the shared sdc HDD, registry PVC at its 50Gi ceiling). The evaluation was grilled to a decision set: - every owned image builds on GitHub Actions and lives on ghcr.io (extends the 2026-06-09 tripit pilot to the whole fleet) - per-repo visibility: 9 public mirrors + images (gated on a clean gitleaks/PII history scan), the personal/finance/gray ones stay private - clean cut: no in-cluster fallback build pipelines; existing build-fallback.yml files are deleted - Woodpecker becomes deploy-only; Forgejo registry freezes to one last-known-good tag per Service after a manual cleanup pass - dead builders (terminal-lobby, webhook-handler, hmrc-sync, trading-bot, travel-agent, trip-planner) are decommissioned, not migrated; travel_blog is decommissioned outright; manual images (x402-gateway, chrome-service-novnc, chatterbox-tts, android-emulator) get formalized GHA builds; infra-ci + CLI builds move to GHA on the public infra repo CONTEXT.md: updated 'GHA build + Woodpecker deploy', added 'Canonical repo', 'GitHub mirror', 'Forgejo registry' terms, image-path relationship, and a 'registry' ambiguity entry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
3978eec53a
commit
623d34628a
2 changed files with 40 additions and 2 deletions
18
CONTEXT.md
18
CONTEXT.md
|
|
@ -169,8 +169,20 @@ A user-managed secret committed to a Stack directory as `sealed-*.yaml`. Distinc
|
|||
### CI/CD
|
||||
|
||||
**GHA build + Woodpecker deploy**:
|
||||
The split where Docker images are built+pushed by GitHub Actions and Woodpecker only runs `kubectl set image` on a deploy-only pipeline. Repos that can't fit GHA limits stay on Woodpecker for build too.
|
||||
_Avoid_: bare "Woodpecker pipeline" — say "build" or "deploy".
|
||||
The split where every owned image is built+pushed by GitHub Actions and Woodpecker only runs `kubectl set image` on a deploy-only pipeline (ADR-0002). Woodpecker never builds images.
|
||||
_Avoid_: bare "Woodpecker pipeline" — say "build" or "deploy"; "fallback build" (the in-cluster fallback path was removed by ADR-0002).
|
||||
|
||||
**Canonical repo**:
|
||||
The Forgejo `viktor/<name>` repo — the only place commits land, workflow files included.
|
||||
_Avoid_: "upstream" (ambiguous); committing anywhere else.
|
||||
|
||||
**GitHub mirror**:
|
||||
The GitHub repo a **Canonical repo** push-mirrors to, one-way, so GitHub Actions can build from it; anything committed on the mirror is silently overwritten by the next sync.
|
||||
_Avoid_: treating it as a second writable remote; bare "the GitHub repo" without saying mirror.
|
||||
|
||||
**Forgejo registry**:
|
||||
Forgejo's built-in container registry — since ADR-0002 a frozen archive holding one last-known-good tag per **Service**, not a build target; owned images live on ghcr.io.
|
||||
_Avoid_: "private registry" (collides with the registry VM's pull-through caches); pushing new images to it.
|
||||
|
||||
**Keel**:
|
||||
The **poll-driven** rollout orchestrator — watches registries for new image tags and rolls the matching Deployments automatically. The actor behind "auto-upgrade" for upstream images, and a redundant net for owned apps (already rolled on push by **Woodpecker deploy**).
|
||||
|
|
@ -192,6 +204,7 @@ A PoW reverse-proxy issuing a 30-day JWT cookie, used in front of public content
|
|||
- A **proxmox-lvm-encrypted** PVC binds to one Node at a time (RWO) and requires a Service-level backup CronJob; an **NFS volume** is RWX and is backed up at the host level via rsync.
|
||||
- **State tier** and **Namespace tier** are orthogonal — a Tier 0 Stack can deploy a Service into any Namespace tier and vice versa.
|
||||
- A **Service**'s image reaches the cluster via **Woodpecker deploy** (push-driven, on commit) or **Keel** (poll-driven, on a new registry tag); **Diun** only notifies. Operator-managed StatefulSets are rolled by neither.
|
||||
- An owned **Service**'s image is built by GitHub Actions from the **Canonical repo**'s **GitHub mirror** and hosted on ghcr.io (ADR-0002); the **Forgejo registry** keeps only a frozen last-known-good tag per **Service**.
|
||||
- Tier-1 **State tier** state and ~12 app databases share one **CNPG** `pg-cluster`, reached through **PgBouncer**; their credentials rotate via the `vault-database` store.
|
||||
|
||||
## Example dialogue
|
||||
|
|
@ -211,3 +224,4 @@ A PoW reverse-proxy issuing a 30-day JWT cookie, used in front of public content
|
|||
- **"secret"** spans Vault entries, K8s Secret objects, **ExternalSecrets**, and **Sealed Secrets**. Always specify which.
|
||||
- **"proxied"** / **"non-proxied"** refer to Cloudflare's CDN posture for a DNS record, _not_ Anubis or forward-auth layering.
|
||||
- **"policy"** spans **Kyverno policy** (admission-time mutate/generate/validate), **Calico NetworkPolicy** (data-path ingress/egress), Vault policy (KV access), and K8s RBAC. Always qualify which engine.
|
||||
- **"registry"** spans three things: ghcr.io (where owned images live, ADR-0002), the **Forgejo registry** (frozen last-known-good archive), and the registry VM's pull-through caches (read-only proxies of upstream registries). Name which one.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue