generated from coulomb/repo-seed
chore(deploy): add railiance handoff guardrails [skip ci]
This commit is contained in:
@@ -224,47 +224,63 @@ state_hub_task_id: "926f82d1-15cd-425d-8a41-3d6b51c07f0b"
|
||||
Create `deploy/railiance/secrets/inter-hub.env.sops.yaml` with:
|
||||
|
||||
```yaml
|
||||
# sops encrypted — do not edit manually
|
||||
DATABASE_URL: postgresql://interhub:<pass>@pgpool.railiance-platform.svc:5432/interhub
|
||||
IHP_SESSION_SECRET: <64-char-hex>
|
||||
IHP_BASEURL: https://hub.coulomb.social
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: inter-hub-env
|
||||
namespace: inter-hub
|
||||
type: Opaque
|
||||
stringData:
|
||||
DATABASE_URL: postgresql://interhub:<pass>@net-kingdom-pg-rw.databases.svc.cluster.local:5432/interhub?sslmode=disable
|
||||
IHP_SESSION_SECRET: <64-char-hex>
|
||||
IHP_BASEURL: https://hub.coulomb.social
|
||||
PORT: "8000"
|
||||
IHP_ENV: Production
|
||||
```
|
||||
|
||||
Encrypt with the age key:
|
||||
```bash
|
||||
sops --encrypt --age $(cat ~/.config/sops/age/keys.txt | grep public | awk '{print $4}') \
|
||||
deploy/railiance/secrets/inter-hub.env.sops.yaml > deploy/railiance/secrets/inter-hub.env.sops.yaml
|
||||
sops --encrypt \
|
||||
--age age1aq8twfd78wvpra0had8cezcnj96tj4q0068edrz5jez8d6xwmflqdepsh4 \
|
||||
/tmp/inter-hub-env.yaml > deploy/railiance/secrets/inter-hub.env.sops.yaml
|
||||
```
|
||||
|
||||
Commit the encrypted file. The Gitea Actions workflow decrypts at deploy time
|
||||
using the age key from a Kubernetes Secret (bootstrapped once manually).
|
||||
Commit only the encrypted file. Apply it with
|
||||
`sops -d deploy/railiance/secrets/inter-hub.env.sops.yaml | kubectl apply -f -`.
|
||||
|
||||
**Recovery note (2026-06-14):** Runtime secrets were bootstrapped manually in
|
||||
Kubernetes so production could deploy safely. This task remains in progress
|
||||
until the durable SOPS-encrypted source for `DATABASE_URL`, `IHP_SESSION_SECRET`,
|
||||
and related runtime env is committed and wired into the deploy path.
|
||||
|
||||
**Progress note (2026-06-14):** Added repo root `.sops.yaml`, plaintext
|
||||
guardrails under `deploy/railiance/secrets/`, an example Secret manifest, and
|
||||
`k8s-secret-json-to-sops-input.py` to convert the live Kubernetes Secret into a
|
||||
SOPS-ready manifest without printing values. This remains in progress because
|
||||
`deploy/railiance/secrets/inter-hub.env.sops.yaml` is not committed yet; local
|
||||
`sops` tooling was not available during this session.
|
||||
|
||||
### R6 — Helm chart in railiance-apps
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0018-T06
|
||||
status: in_progress
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "4c4acc98-5773-4289-ad57-03f3fd5c381c"
|
||||
```
|
||||
Create `helm/inter-hub/` in the `railiance-apps` repository following the
|
||||
Create `charts/inter-hub/` in the `railiance-apps` repository following the
|
||||
Railiance app.toml contract. Minimal chart:
|
||||
|
||||
```
|
||||
helm/inter-hub/
|
||||
charts/inter-hub/
|
||||
Chart.yaml name: inter-hub, version: 0.1.0
|
||||
values.yaml image.tag, ingress.host, resources
|
||||
values.prod.yaml replicas: 1, resources.requests.memory: 1Gi
|
||||
helm/inter-hub-values.yaml
|
||||
production non-secret overrides
|
||||
templates/
|
||||
deployment.yaml envFrom: secretRef inter-hub-env
|
||||
service.yaml ClusterIP :8000
|
||||
ingress.yaml Traefik annotations, TLS
|
||||
secret.yaml created by sops-operator or external-secrets
|
||||
```
|
||||
|
||||
`app.toml` in the inter-hub repo root for railiance CLI integration:
|
||||
@@ -273,10 +289,10 @@ helm/inter-hub/
|
||||
name = "inter-hub"
|
||||
slug = "inter-hub"
|
||||
kind = "native"
|
||||
registry = "registry.coulomb.social/coulomb/inter-hub"
|
||||
registry = "gitea.coulomb.social/coulomb/inter-hub"
|
||||
|
||||
[deploy]
|
||||
chart = "railiance-apps/helm/inter-hub"
|
||||
chart = "railiance-apps/charts/inter-hub"
|
||||
namespace = "inter-hub"
|
||||
```
|
||||
|
||||
@@ -291,6 +307,11 @@ successfully deployed the app to Railiance01. This task remains in progress
|
||||
because the repo-root `app.toml` and railiance-apps handoff are still not
|
||||
completed.
|
||||
|
||||
**Completion note (2026-06-14):** Added repo-root `app.toml` in inter-hub and
|
||||
added `charts/inter-hub`, `helm/inter-hub-values.yaml`, Makefile targets, and
|
||||
server-dry-run coverage in `railiance-apps`. The chart rendered successfully on
|
||||
haskelseed with `helm template`.
|
||||
|
||||
### R7 — Gitea Actions CI/CD pipeline
|
||||
|
||||
```task
|
||||
@@ -358,6 +379,11 @@ token from the repo `REGISTRY_TOKEN` Actions secret, deploys with Helm, and
|
||||
runs public smoke checks. Gitea Actions run `2913` completed successfully for
|
||||
commit `5663fab`.
|
||||
|
||||
**Load-control note (2026-06-14):** Added workflow `paths-ignore` for docs,
|
||||
workplans, `.custodian-brief.md`, `app.toml`, `.sops.yaml`, and
|
||||
`deploy/railiance/**` so State Hub consistency/doc-only commits do not consume a
|
||||
haskelseed build/deploy cycle.
|
||||
|
||||
### R8 — Staged deployment and smoke test
|
||||
|
||||
```task
|
||||
@@ -398,7 +424,7 @@ and unauthenticated `/api/v2/widgets` returns 401.
|
||||
|
||||
```task
|
||||
id: IHUB-WP-0018-T09
|
||||
status: in_progress
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "4d1e55c7-8dbb-480f-b07b-6c5e39a04218"
|
||||
```
|
||||
@@ -420,6 +446,12 @@ deployment evidence has been recorded here. Remaining documentation work is to
|
||||
capture the durable secret-management and railiance-apps handoff path once R5
|
||||
and R6 are completed.
|
||||
|
||||
**Completion note (2026-06-14):** Updated `deploy/railiance/RUNBOOK.md` for the
|
||||
current Gitea registry host, runner-based build/deploy path, SOPS secret handoff,
|
||||
current smoke checks, and haskelseed's build-runner-only role. Updated
|
||||
`docs/new-hub-quickstart.md` so haskelseed is no longer described as a
|
||||
production/shared database runtime.
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- `https://hub.coulomb.social/` returns the Landing page (200, no auth)
|
||||
|
||||
Reference in New Issue
Block a user