Serve the rebuild on app.coulomb.social; defer apex Bubble cutover
Document parallel-host strategy: Railiance on app.*, Bubble remains on coulomb.social until data and self-registration are ready.
This commit is contained in:
parent
fe8b96a388
commit
f5537d8365
4 changed files with 46 additions and 89 deletions
|
|
@ -23,7 +23,7 @@ This repository is the **owning home** for the rebuild:
|
|||
1. **Parity capture** — inventory and export everything that matters in the bubble.io app (UI surfaces, workflows, data types, content, integrations).
|
||||
2. **Cut decisions** — decide rebuild-as-is vs reduced v1 with an explicit human gate.
|
||||
3. **Implementation** — deliver a standalone service on the proven business delivery lane (`vergabe-teilnahme` evidence), under the business-app service contract.
|
||||
4. **Cutover** — migrate members and content off bubble.io when the new stack is ready.
|
||||
4. **Cutover** — serve the rebuild on **`app.coulomb.social`** in parallel with Bubble on apex `coulomb.social`; retire Bubble only when data, self-registration, and content parity are ready.
|
||||
|
||||
Binky Hedgehog GmbH is **client #1** of its own platform (DR-2 B). The app is not a Core Hub extension; it is a normal client-facing business application.
|
||||
|
||||
|
|
|
|||
113
docs/deploy.md
113
docs/deploy.md
|
|
@ -9,118 +9,71 @@ railiance01 (same lane as `vergabe-teilnahme`).
|
|||
Chart/values/ingress live in **`railiance-apps`**
|
||||
(`helm/coulomb-social-values.yaml`, `docs/coulomb-social.md`).
|
||||
|
||||
## Current cluster status (2026-08-09)
|
||||
## Host strategy
|
||||
|
||||
| Host | Role |
|
||||
|------|------|
|
||||
| **`https://app.coulomb.social`** | **Live** Railiance rebuild (identity shell now; product later) |
|
||||
| **`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` Active |
|
||||
| Deployment | 1/1 Ready, image `:7067145` |
|
||||
| Service | ClusterIP :80 |
|
||||
| Ingress | `coulomb.social` → Traefik, cert-manager annotation |
|
||||
| Env secret | `coulomb-social-env` (`SECRET_KEY`, `DATABASE_URL`, `USER_ENGINE_PROXY_SECRET`) |
|
||||
| OIDC | enabled; issuer `https://kc.coulomb.social`; public client |
|
||||
| Public DNS | **still Cloudflare / Bubble** |
|
||||
| TLS secret | **pending** HTTP-01 until DNS points at the cluster |
|
||||
|
||||
In-cluster smoke (with `Host: coulomb.social`): `/healthz` ok, landing 200,
|
||||
`/auth/login/` → KeyCape authorize. Full browser session needs cutover.
|
||||
| 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` in namespace `coulomb-social` (chart `envFrom`):
|
||||
|
||||
| Key | Source |
|
||||
|-----|--------|
|
||||
| `SECRET_KEY` | generated by env-secret script |
|
||||
| `DATABASE_URL` | cnpg app role secret (URL-encoded password) |
|
||||
| `USER_ENGINE_PROXY_SECRET` | `user-engine/user-engine-runtime` |
|
||||
K8s Secret `coulomb-social-env` (`SECRET_KEY`, `DATABASE_URL`, `USER_ENGINE_PROXY_SECRET`).
|
||||
|
||||
```bash
|
||||
# from railiance-apps:
|
||||
# railiance-apps:
|
||||
make coulomb-social-env-secret-dry-run
|
||||
make coulomb-social-env-secret
|
||||
|
||||
# from this repo:
|
||||
./scripts/create-env-secret.sh --dry-run
|
||||
./scripts/create-env-secret.sh
|
||||
```
|
||||
|
||||
OIDC is a **public** client — no client secret.
|
||||
|
||||
Non-secret env (OIDC, ALLOWED_HOSTS, user-engine URL) lives in Helm values.
|
||||
|
||||
## Health
|
||||
|
||||
- `GET /healthz` → `{"status":"ok","service":"coulomb-social"}`
|
||||
- Probes use `Host: coulomb.social` (`probes.hostHeader`)
|
||||
- Probes use `Host: app.coulomb.social`
|
||||
|
||||
## Build / deploy
|
||||
|
||||
```bash
|
||||
SHA=$(git rev-parse --short HEAD)
|
||||
docker build -t forgejo.coulomb.social/coulomb/coulomb-social:$SHA .
|
||||
# push, then:
|
||||
# COULOMB_SOCIAL_IMAGE_TAG=$SHA make coulomb-social-deploy # in railiance-apps
|
||||
# make coulomb-social-ingress-deploy
|
||||
```
|
||||
|
||||
## Cutover checklist (DNS → live Railiance)
|
||||
## Parallel host go-live checklist
|
||||
|
||||
**Goal:** `https://coulomb.social` serves this app (identity shell), not Bubble.
|
||||
1. [x] Helm env / ingress use `app.coulomb.social`
|
||||
2. [x] KeyCape redirects include `https://app.coulomb.social/auth/callback/`
|
||||
3. [ ] DNS: `app.coulomb.social` **A → `92.205.62.239`** (prefer DNS-only for LE)
|
||||
4. [ ] `certificate/coulomb-social-tls` Ready for `app.coulomb.social`
|
||||
5. [ ] `curl -fsS https://app.coulomb.social/healthz`
|
||||
6. [ ] Browser Sign in as tegwick → `/app/`
|
||||
|
||||
### Preconditions
|
||||
## Future apex cutover (not now)
|
||||
|
||||
1. [x] Image + Helm release healthy
|
||||
2. [x] KeyCape client `coulomb-social` with prod redirect `https://coulomb.social/auth/callback/`
|
||||
3. [x] In-cluster OIDC start redirect works
|
||||
4. [ ] Local browser OIDC + MFA completed once (proves IdP + user-engine path)
|
||||
5. [ ] Operator accepts brief public outage / Bubble freeze during DNS switch
|
||||
6. [ ] Optional: export Bubble data if still needed (CSOC-WP-0001) — not required for identity-only cutover
|
||||
When Bubble can retire:
|
||||
|
||||
### DNS switch
|
||||
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
|
||||
|
||||
1. In Cloudflare (or DNS host): lower TTL on `coulomb.social` if possible (e.g. 300s) ahead of time.
|
||||
2. Point apex (and `www` if used) **A** to **`92.205.62.239`** (railiance01 ingress).
|
||||
- Prefer DNS-only (grey cloud) first so LE HTTP-01 and Traefik see real traffic; re-enable proxy only if you understand TLS termination path.
|
||||
3. Wait for propagation: `dig +short coulomb.social A` → `92.205.62.239`.
|
||||
4. cert-manager should finish HTTP-01; confirm:
|
||||
|
||||
```bash
|
||||
kubectl -n coulomb-social get certificate coulomb-social-tls
|
||||
# READY=True
|
||||
```
|
||||
|
||||
5. Smoke public HTTPS:
|
||||
|
||||
```bash
|
||||
curl -fsS https://coulomb.social/healthz
|
||||
curl -sI https://coulomb.social/auth/login/ | grep -i location
|
||||
# Location: https://kc.coulomb.social/authorize?...
|
||||
```
|
||||
|
||||
6. **Browser:** Sign in → Authelia MFA → land on `/app/` with principal.
|
||||
7. Sign out; confirm `/app/` requires login.
|
||||
8. Second login: same member row / user-engine user_id.
|
||||
|
||||
### Rollback
|
||||
|
||||
- Point DNS A (or Cloudflare origin) back to Bubble/Cloudflare target.
|
||||
- Cluster release can stay; it only receives traffic when DNS aims at the node.
|
||||
|
||||
### After cutover residuals
|
||||
|
||||
| Item | Note |
|
||||
|------|------|
|
||||
| Bubble freeze | Stop editing live Bubble as source of truth |
|
||||
| Content/UI | CSOC-WP-0001 + design extract — not required for identity shell |
|
||||
| flex-auth Service | leave `FLEX_AUTH_BASE_URL` unset (local vocabulary) until PDP exists |
|
||||
| apps-pg backup/HA | business-app contract |
|
||||
| OpenBao CCR | replace kubectl-sourced env secret when ready |
|
||||
| Image CI | Forgejo/Gitea pipeline for SHA tags |
|
||||
|
||||
## Local verification (no cutover)
|
||||
## Local verification
|
||||
|
||||
```bash
|
||||
make test
|
||||
make run # offline identity
|
||||
# or OIDC vars from docs/identity/oidc-client.md
|
||||
make run # offline or local OIDC redirect
|
||||
```
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ Non-secret registration checklist for NetKingdom IAM Profile issuers.
|
|||
| client_id | `coulomb-social` |
|
||||
| client_type | **public** (no client secret; PKCE only) |
|
||||
| redirect_uri (dev) | `http://127.0.0.1:8008/auth/callback/` · `http://localhost:8008/auth/callback/` |
|
||||
| redirect_uri (prod) | `https://coulomb.social/auth/callback/` |
|
||||
| redirect_uri (public app) | `https://app.coulomb.social/auth/callback/` (**live** host while Bubble keeps apex) |
|
||||
| redirect_uri (apex future) | `https://coulomb.social/auth/callback/` (registered; cutover deferred) |
|
||||
| scopes | `openid profile email groups` |
|
||||
| grant | authorization_code |
|
||||
| wildcard redirects | **forbidden** |
|
||||
|
|
|
|||
|
|
@ -90,12 +90,15 @@ Unregistered redirects still fail with `invalid_profile_usage` (T03).
|
|||
make test
|
||||
```
|
||||
|
||||
## Blockers for production hostname smoke
|
||||
## Public host (parallel to Bubble)
|
||||
|
||||
| Blocker | Detail |
|
||||
|---------|--------|
|
||||
| Public DNS | `coulomb.social` → Cloudflare `104.*` (Bubble), not `92.205.62.239` |
|
||||
| TLS cert | `certificate/coulomb-social-tls` **not Ready**; HTTP-01 challenge gets **404** from public edge (LE never reaches cluster solver) |
|
||||
| Secure cookies | prod `SESSION_COOKIE_SECURE=True` — need HTTPS after cutover |
|
||||
**Strategy:** live Railiance app on **`app.coulomb.social`**; apex **`coulomb.social`** stays Bubble until content + self-registration cutover.
|
||||
|
||||
See cutover steps in `docs/deploy.md`.
|
||||
| Check | Detail |
|
||||
|-------|--------|
|
||||
| Cluster host | `app.coulomb.social` (Helm + ingress) |
|
||||
| OIDC redirect | `https://app.coulomb.social/auth/callback/` |
|
||||
| DNS | operator: `app.coulomb.social` A → `92.205.62.239` |
|
||||
| Apex | **do not** repoint until Bubble retirement |
|
||||
|
||||
See `docs/deploy.md`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue