diff --git a/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md b/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md index 84a5f86..b232c1c 100644 --- a/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md +++ b/workplans/railiance-apps-WP-0002-vergabe-teilnahme-on-railiance01.md @@ -11,6 +11,7 @@ created: "2026-05-18" updated: "2026-05-18" planning_priority: high planning_order: 2 +state_hub_workstream_id: "94522a85-80d5-4f2c-8eb0-8d0bcb15f3b0" --- # Establish vergabe-teilnahme as an Application on railiance01 @@ -115,8 +116,9 @@ Cross-repo coordination required: ```task id: RAILIANCE-WP-0002-T01 -status: todo +status: done priority: high +state_hub_task_id: "49aa7d85-96bd-4d97-952c-80dcfff06610" ``` Confirm the pre-conditions before any code is written. @@ -139,6 +141,54 @@ Checks: (b) the operator's path to a Gitea package token, (c) the DNS change path for `whywhynot.de`, and (d) any pre-condition gaps. +**Findings (2026-05-18):** + +- **cnpg landscape — no shared cluster yet.** `kubectl get clusters.postgresql.cnpg.io -A` returns two + app-dedicated clusters in the `databases` namespace: + - `gitea-db` — `ghcr.io/cloudnative-pg/postgresql:18.1-system-trixie`, 1 instance, 10Gi + - `net-kingdom-pg` — `ghcr.io/cloudnative-pg/postgresql:16`, 1 instance, 10Gi + Neither was provisioned as a shared cluster. The user's earlier choice + ("shared cnpg cluster, new database role") therefore requires a sub-decision — + see **Decision D-01** below. +- **Gitea registry reachable.** `curl --resolve gitea.coulomb.social:443:92.205.130.254 + https://gitea.coulomb.social/v2/` returns `HTTP 405` for `HEAD` with a valid TLS chain + (cert: `default/gitea-tls`, ready 3d). The OCI endpoint is up; HEAD-vs-GET is expected. +- **Gitea package token — still required.** No package-capable PAT is currently held + by the operator in this session (carryover blocker from `RAILIANCE-WP-0001-T04`). + Token must be minted via the Gitea web UI by a user with `write:package` scope before T03. +- **Public DNS for `whywhynot.de`:** A-record currently `217.160.0.212` (IONOS web hosting). + Authoritative NS = `ns1126.ui-dns.{de,biz,com,org}` (IONOS / 1&1). The zone is + administered through the operator's IONOS web console — DNS change is a manual + out-of-band step. +- **Traefik LB public IP:** `92.205.130.254` (`kube-system/traefik` LoadBalancer service, + ports 80/443). This is the target the new A-record must point at. +- **cert-manager:** `ClusterIssuer/letsencrypt-prod` is `Ready=True` (59d). Most recent + successful issuance: `default/gitea-tls`, 3d4h ago. Several stale failing certs in + `mfa` and `sso` namespaces are unrelated to this workplan. +- **Pre-condition gaps before downstream tasks unblock:** + 1. D-01 below (cnpg target cluster) — blocks T04. + 2. Gitea package-capable PAT — blocks T03. + 3. DNS A-record for `vergabe-teilnahme.whywhynot.de → 92.205.130.254` — + blocks T06. + +**Decision D-01 — cnpg target for `vergabe_db`** (pending; required before T04): + +| Option | Pros | Cons | +|--------|------|------| +| A. New dedicated cluster `vergabe-pg` | Matches the existing one-cluster-per-app pattern; clean blast radius | Resource cost grows linearly with apps; no actual "shared" cluster emerges | +| B. Add role+db to existing `net-kingdom-pg` (PG 16) | Reuses a healthy PG 16 cluster matching vergabe-teilnahme's minimum; lowest cost | Cluster name no longer reflects its content; coupling with netkingdom domain | +| C. Add role+db to existing `gitea-db` (PG 18) | Newest cluster image; same operator | Couples gitea ops with vergabe ops; name no longer reflects content | +| D. Provision a new general-purpose cluster `apps-pg` (PG 16+) | Establishes a real shared cluster that future apps adopt | Net-new infra; needs a `railiance-platform` task to own the cluster | + +Recommendation: **D** (creates the "shared cluster" the user asked for as a real +artifact rather than retrofitting an existing name). Recorded as a pending hub decision. + +**Resolution (2026-05-18, bernd):** Option D. Provision a new shared cnpg cluster +`apps-pg` (PG 16, 1 instance, 10Gi initial) in namespace `databases`. cnpg `Cluster` +CRs live in `railiance-platform` per ADR-003 (confirmed: `helm/gitea-db-cluster.yaml`). +A coordination message has been sent to `railiance-platform` requesting the cluster. +T04 below is now sequenced **after** that cluster reports healthy. + --- ### T02 — Add Dockerfile and asset build to vergabe-teilnahme @@ -148,6 +198,7 @@ id: RAILIANCE-WP-0002-T02 status: todo priority: high repo: vergabe-teilnahme +state_hub_task_id: "43ce85c4-0bdb-43c4-b0a5-81fa366800a6" ``` Open a companion task in the `vergabe-teilnahme` repo to add a @@ -182,6 +233,7 @@ a runnable image that responds to a smoke request locally. id: RAILIANCE-WP-0002-T03 status: todo priority: high +state_hub_task_id: "d0f8db8c-fad9-4e0b-a404-9e3a04cffb05" ``` Push the first production image of vergabe-teilnahme through the @@ -208,22 +260,30 @@ on the cluster. ```task id: RAILIANCE-WP-0002-T04 -status: todo +status: blocked priority: high +state_hub_task_id: "925ace1c-f9bf-4644-bd0b-637705d72ea6" ``` Create a `vergabe` PostgreSQL role and `vergabe_db` database inside the -shared cnpg cluster identified in T01. +new shared `apps-pg` cnpg cluster being provisioned by `railiance-platform` +(per resolved decision D-01). + +Blocked on: `apps-pg` cluster reaching `Cluster in healthy state` in +namespace `databases`. Coordination message sent to `railiance-platform` +on 2026-05-18; record the platform workstream/task IDs here once +returned. Approach: -- Use a cnpg `Database` and `Role` (or `ScheduledBackup` / SQL bootstrap) - resource — never an out-of-band `psql` change without recording it. +- Use a cnpg `Database` and `Role` resource — never an out-of-band `psql` + change without recording it. - The role owns only `vergabe_db`; no `CREATEDB`, no superuser, no grants on other databases. - Capture the database DSN in the SOPS values file (T05). -- Coordinate with `railiance-platform` if any cluster-level change is - needed (resource limits, backup inclusion, monitoring). +- If the cluster needs to grow (more instances, more storage, backup + inclusion), pause and add a follow-up `railiance-platform` task — do + not edit cluster-level resources from this repo. **Done when:** the new role can connect to `vergabe_db` from inside the cluster (`kubectl run --rm -it psql ...`) and is recorded in the SOPS @@ -237,6 +297,7 @@ values used by T05. id: RAILIANCE-WP-0002-T05 status: todo priority: high +state_hub_task_id: "29ba6add-6f23-4053-acb9-9d7efa0b3881" ``` Add the chart selection (or bespoke chart) and SOPS-encrypted values @@ -272,6 +333,7 @@ and produces no plaintext secrets in the rendered manifest source. id: RAILIANCE-WP-0002-T06 status: todo priority: high +state_hub_task_id: "8e673ee6-5338-4eb5-8973-a1818b4dc7f5" ``` Make the application reachable behind a valid Let's Encrypt certificate. @@ -305,6 +367,7 @@ certificate chain validates from outside the cluster. id: RAILIANCE-WP-0002-T07 status: todo priority: high +state_hub_task_id: "be1decb5-b734-4312-b98d-20ed5299d02c" ``` Bring the app to a usable state in production. @@ -335,6 +398,7 @@ unexpected errors. id: RAILIANCE-WP-0002-T08 status: todo priority: medium +state_hub_task_id: "594d3591-b61f-40c4-850c-efaa02c859ed" ``` Capture everything an on-call operator needs.