coulomb-social/docs/deploy.md
tegwick edfdd79208 Finish CSOC-WP-0003 and CSOC-WP-0004; residual intakes for Case B
Close self-registration workplan with Case A proven and Create account
entry implemented; park public registration enablement and identity
negatives as CSOC-IN-0001/0002. Complete app-shell workplan with T06
operator runbook (seed, bind, webhook, smoke) and smoke doc updates.
2026-08-12 10:59:25 +02:00

7.3 KiB

Deploy notes

Shape

Standalone service: commit-SHA images → registry forgejo.coulomb.social/coulomb/coulomb-socialrailiance-apps Helm values → railiance01 (same lane as vergabe-teilnahme).

Chart/values/ingress live in railiance-apps (helm/coulomb-social-values.yaml, docs/coulomb-social.md).

Host strategy

Host Role
https://app.coulomb.social Live Railiance rebuild (app home + spaces)
https://coulomb.social Bubble.io until data + self-registration + content ready
http://127.0.0.1:8008 Local OIDC/dev

Apex DNS cutover is deferred. Retire Bubble only after an explicit decision.

Current cluster status

Item State
Namespace coulomb-social
Public host app.coulomb.social
OIDC redirect https://app.coulomb.social/auth/callback/
Apex Bubble unchanged

Runtime secrets (names only)

K8s Secret coulomb-social-env (mounted via envFrom).

Key Required Purpose
SECRET_KEY yes Django secret
DATABASE_URL yes Postgres URL
USER_ENGINE_PROXY_SECRET yes (live UE) trusted proxy to user-engine
FORGEJO_TOKEN no private Forgejo raw/API reads
FORGEJO_WEBHOOK_SECRET no push webhook HMAC / shared secret
NETKINGDOM_REGISTRATION_URL no enable landing Create account when NK ships
# railiance-apps:
make coulomb-social-env-secret-dry-run
make coulomb-social-env-secret

OIDC is a public client — no client secret. Non-secret OIDC / Forgejo base URL settings live in Helm values (FORGEJO_BASE_URL defaults to https://forgejo.coulomb.social in app settings).

Health

  • GET /healthz{"status":"ok","service":"coulomb-social"}
  • Probes use Host: app.coulomb.social

Build / deploy

SHA=$(git rev-parse --short HEAD)
docker build -t forgejo.coulomb.social/coulomb/coulomb-social:$SHA .
# COULOMB_SOCIAL_IMAGE_TAG=$SHA make coulomb-social-deploy   # in railiance-apps
# make coulomb-social-ingress-deploy

Parallel host go-live checklist

  1. Helm env / ingress use app.coulomb.social
  2. KeyCape redirects include https://app.coulomb.social/auth/callback/
  3. DNS: app.coulomb.social resolves; HTTPS live (healthz 200)
  4. curl -fsS https://app.coulomb.social/healthz
  5. Browser Sign in as tegwick → /app/ (Case A; see docs/identity/smoke.md)
  6. Seed demo space + open rendered markdown (operator; steps below)

Future apex cutover (not now)

When Bubble can retire:

  1. Point coulomb.social A at the cluster (or reverse-proxy)
  2. Switch Helm ALLOWED_HOSTS / OIDC_REDIRECT_URI / ingress host if apex becomes canonical
  3. Keep or drop app. as redirect alias

Local verification

make test
make run   # offline or local OIDC redirect
uv run manage.py seed_demo_space
# Sign in (dev login) → /app/ → Demo space → rendered markdown

Operator runbook — spaces on app.coulomb.social

Product path for CSOC-WP-0004. Content model: ADR-0002. Detail on read/write/webhook: docs/spaces-content.md. Identity smoke: docs/identity/smoke.md.

A. Prerequisites

  1. Image includes spaces app (spaces migrations + Forgejo client) and is deployed to namespace coulomb-social.
  2. Member can Sign in (existing LLDAP/KeyCape user, e.g. tegwick).
  3. Forgejo reachable from the pod (FORGEJO_BASE_URL, default https://forgejo.coulomb.social). Public raw needs no token; private repos need FORGEJO_TOKEN in coulomb-social-env.

B. Demo seed (fastest smoke — uses this repo as content)

In-repo fixture (already on main):

docs/space-fixtures/demo/pages/index.md

Public raw check (no auth):

curl -fsS \
  "https://forgejo.coulomb.social/coulomb/coulomb-social/raw/branch/main/docs/space-fixtures/demo/pages/index.md" \
  | head

Seed metadata in the app DB (binds demo → that path):

kubectl -n coulomb-social exec deploy/coulomb-social -- \
  python manage.py seed_demo_space
# optional: --slug demo --title "Demo space" --tenant tenant:coulomb

Browser:

  1. https://app.coulomb.social/Sign in (tegwick)
  2. Land on /app/Spaces lists Demo space
  3. Open /app/spaces/demo/ — see rendered markdown from Forgejo
  4. Profile menu → Session details (/account/session/) still works
  5. Edit in Forgejo / View source open the bound file; after a commit, Refresh content re-fetches (or configure webhook, section D)

C. Production-shaped space (dedicated Forgejo repo)

ADR-0002: one repo per space.

  1. In Forgejo, create org (recommended) coulomb-spaces (or tenant org later).
  2. Create repo e.g. space-my-space with branch main and layout:
pages/
  index.md          # default landing page
  <page-slug>.md    # optional extra pages
assets/             # optional images
README.md           # optional
  1. Bind in the app (Django admin, or shell):
kubectl -n coulomb-social exec -it deploy/coulomb-social -- python manage.py shell
from coulomb_social.apps.spaces.models import Space
Space.objects.update_or_create(
    tenant_id="tenant:coulomb",
    slug="my-space",
    defaults={
        "title": "My space",
        "forgejo_owner": "coulomb-spaces",
        "forgejo_repo": "space-my-space",
        "default_branch": "main",
        "content_root": "pages",
        "is_active": True,
    },
)
  1. If the repo is private, set FORGEJO_TOKEN (read-only deploy token) via railiance-apps env-secret tooling — never commit the token.
  2. Open https://app.coulomb.social/app/spaces/my-space/ as a signed-in member of that tenant.

D. Optional push webhook (auto cache bust)

  1. Put a random secret in cluster env as FORGEJO_WEBHOOK_SECRET.
  2. Forgejo repo → Settings → Webhooks → Add webhook → Gitea:
    • URL: https://app.coulomb.social/app/spaces/hooks/forgejo/
    • Method POST, content type JSON
    • Secret: same value as env
    • Trigger: Push
  3. Push a commit; confirm response JSON includes cache_entries_cleared / spaces_matched. Authors can still use Refresh content without a webhook.

E. Env names quick reference

Variable Secret? Where
FORGEJO_BASE_URL no settings default / Helm
FORGEJO_TOKEN yes coulomb-social-env
FORGEJO_WEBHOOK_SECRET yes coulomb-social-env
FORGEJO_TIMEOUT_SECONDS no optional
NETKINGDOM_REGISTRATION_URL no enable Create account (residual; NK-WP-0025)

F. Smoke checklist (app.coulomb.social)

# Check Pass criteria
1 GET /healthz {"status":"ok","service":"coulomb-social"}
2 Landing Sign in visible; Create account only if registration URL set
3 OIDC login (known user) tegwick → /app/ app home (not principal dump)
4 Spaces list empty state or seeded spaces
5 Space detail markdown rendered from Forgejo (or clear fail-closed error)
6 Session details profile menu → /account/session/ shows issuer/subject/UE id
7 Sign out session cleared; /app/ requires login
8 (optional) Edit in Forgejo + Refresh new commit visible without redeploy

Identity detail and historical evidence: docs/identity/smoke.md. Content mechanics: docs/spaces-content.md.