Merge remote-tracking branch 'origin/dev' into fix/registry-namespace-admin-emi
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 5s
shell-lint / shellcheck (pull_request) Successful in 7s
PR build (required check) / validate-observability (pull_request) Successful in 16s
PR build (required check) / build-frontend (pull_request) Successful in 21s
PR build (required check) / build-backend (pull_request) Successful in 42s
PR build (required check) / gate (pull_request) Successful in 1s
All checks were successful
PR build (required check) / changes (pull_request) Successful in 6s
secrets-guard / encrypted (pull_request) Successful in 5s
shell-lint / shellcheck (pull_request) Successful in 7s
PR build (required check) / validate-observability (pull_request) Successful in 16s
PR build (required check) / build-frontend (pull_request) Successful in 21s
PR build (required check) / build-backend (pull_request) Successful in 42s
PR build (required check) / gate (pull_request) Successful in 1s
This commit is contained in:
commit
73fcb174ef
6 changed files with 77 additions and 52 deletions
|
|
@ -26,7 +26,7 @@ rather than which environment happens to live there:
|
|||
|
||||
| Host | Public IP | Mesh IP | Role |
|
||||
|------|-----------|---------|------|
|
||||
| **vps1** | `75.119.132.91` | `10.10.0.2` | "Operational programs": Forgejo (git + CI + registry, `git.thermograph.org`, also served at `dev.jinemi.com` — migration in progress, `.org` still canonical), Grafana/Loki/Alloy (`dashboard.thermograph.org`), the `emigriffith.dev` portfolio, and the **dev** environment (mesh-only, `10.10.0.2:8137`, no public DNS/Caddy/TLS) |
|
||||
| **vps1** | `75.119.132.91` | `10.10.0.2` | "Operational programs": Forgejo (git + CI + registry; `dev.jinemi.com` canonical, `git.thermograph.org` still served and still used by the registry/mesh pins/runners), Grafana/Loki/Alloy (`dashboard.thermograph.org`), the `emigriffith.dev` portfolio, and the **dev** environment (mesh-only, `10.10.0.2:8137`, no public DNS/Caddy/TLS) |
|
||||
| **vps2** | `169.58.46.181` | `10.10.0.1` | "The deployed environment": **prod** and **beta**, as two separate Docker Swarm stacks, plus Centralis, Postfix, the backups, and the one shared TimescaleDB instance both stacks use |
|
||||
| **desktop** | — | `10.10.0.3` | AI-model hosting (voice-to-text, an upcoming-feature LLM) plus flex Swarm-worker capacity. Hosts **no** Thermograph environment — `make dev-up` still works there, but only as a laptop-local rehearsal |
|
||||
|
||||
|
|
|
|||
|
|
@ -12,9 +12,10 @@ Two VPS boxes plus the operator's desktop, on one WireGuard mesh, named by
|
|||
ROLE rather than by environment:
|
||||
|
||||
- **vps1** — `75.119.132.91`, mesh `10.10.0.2`. "Operational programs": Forgejo
|
||||
(git + CI + registry, `git.thermograph.org`, also served at `dev.jinemi.com`
|
||||
— one Caddy site block, the `.org` name still canonical; migration in
|
||||
progress, see `deploy/forgejo/README.md`), Grafana/Loki/Alloy
|
||||
(git + CI + registry; `dev.jinemi.com` is canonical — Forgejo's `ROOT_URL` —
|
||||
and `git.thermograph.org` is still served off the same Caddy site block and
|
||||
still load-bearing for the registry, mesh pins and runner URLs, so don't
|
||||
retire it; see `deploy/forgejo/README.md`), Grafana/Loki/Alloy
|
||||
(`dashboard.thermograph.org`), the `emigriffith.dev` portfolio site, and the
|
||||
**dev** environment (`/opt/thermograph-dev`, tracks `dev`), with its own
|
||||
Postgres container. Dev is mesh-only here — published on `10.10.0.2:8137`,
|
||||
|
|
|
|||
|
|
@ -2,10 +2,11 @@
|
|||
#
|
||||
# vps1 serves:
|
||||
# emigriffith.dev -> static portfolio site (from disk)
|
||||
# git.thermograph.org -> Forgejo (see deploy/forgejo/caddy-git.conf)
|
||||
# dev.jinemi.com -> Forgejo, same site block — migration target for
|
||||
# git.thermograph.org, both served, the .org one
|
||||
# still canonical (that file's header explains)
|
||||
# dev.jinemi.com -> Forgejo, CANONICAL (Forgejo's ROOT_URL)
|
||||
# git.thermograph.org -> Forgejo, same site block — still served and
|
||||
# still needed: the registry host in image names,
|
||||
# the mesh /etc/hosts pins and the runners' URLs
|
||||
# all use it (see deploy/forgejo/caddy-git.conf)
|
||||
# dashboard.thermograph.org -> Grafana (see observability/caddy-grafana.conf)
|
||||
#
|
||||
# and hosts the **dev** environment at dev.thermograph.org (below).
|
||||
|
|
|
|||
|
|
@ -85,50 +85,55 @@ pattern as its other site blocks, same automatic-HTTPS.
|
|||
|
||||
## Migrating the domain (git.thermograph.org -> dev.jinemi.com)
|
||||
|
||||
In progress. **Both hostnames are served**; `git.thermograph.org` is still the
|
||||
canonical one.
|
||||
**Web UI and OAuth: done.** `dev.jinemi.com` is Forgejo's `ROOT_URL`
|
||||
(`FORGEJO_DOMAIN` in `docker-stack.yml`), so it is the name Forgejo generates in
|
||||
clone URLs, the Google OAuth callback, webhook payload URLs and mail links.
|
||||
|
||||
**Registry: deliberately not done.** Renaming the registry host is a separate
|
||||
migration from renaming the web UI, and the two need not happen together.
|
||||
|
||||
`caddy-git.conf` lists both names on a *single* site block. That is deliberate,
|
||||
not cosmetic: the `/v2/*` mesh-only matcher is per-block, so a second block for
|
||||
`dev.jinemi.com` would re-expose the registry API publicly and undo hazard #15.
|
||||
either name would re-expose the registry API publicly and undo hazard #15.
|
||||
Whatever else changes, keep the two names in one block.
|
||||
|
||||
Serving a second hostname is the cheap half. Forgejo has exactly one
|
||||
`ROOT_URL`, and it builds every absolute URL from it, so on the non-canonical
|
||||
host today:
|
||||
**`git.thermograph.org` must stay served.** It is not a courtesy redirect for
|
||||
old bookmarks — CI resolves it:
|
||||
|
||||
- clone URLs on repo pages read `git.thermograph.org`,
|
||||
- the OAuth callback and post-login redirect land on `git.thermograph.org`
|
||||
(login is Google-SSO-only — see `docker-stack.yml`),
|
||||
- webhook payload URLs and notification mail links use `git.thermograph.org`.
|
||||
- images are named by registry host, and the `git.thermograph.org/` prefix is
|
||||
baked into the runner labels (`register-lan-runner.sh`,
|
||||
`runner-vps2/README.md`), the CI-runner image (`ci-runner/Dockerfile`),
|
||||
`REGISTRY_HOST` in `infra/.env.example`, and every already-pushed tag;
|
||||
- every mesh client in "Registry access from mesh clients" below pins
|
||||
`git.thermograph.org` to `10.10.0.2` in `/etc/hosts`, which is what makes
|
||||
Caddy's `/v2/*` matcher see a mesh source IP instead of returning 403;
|
||||
- registered runners hold the instance URL they registered with
|
||||
(`https://git.thermograph.org`); they keep working while that name resolves.
|
||||
|
||||
Browsing, git-over-HTTP and the API all work on `dev.jinemi.com` regardless.
|
||||
### Before changing ROOT_URL again
|
||||
|
||||
Flipping canonical (`FORGEJO_DOMAIN=dev.jinemi.com`, then `docker stack deploy`)
|
||||
needs these **first**, or it breaks login and CI rather than just renaming
|
||||
things:
|
||||
Login is Google-SSO-only, so the Google OAuth client must already carry a
|
||||
matching redirect URI, or nobody can reach the UI — including to undo the
|
||||
change. Both of these are registered on client
|
||||
`337247886376-4360kepi20f24pue62ptg0lnqhcht46l.apps.googleusercontent.com`:
|
||||
|
||||
1. **Google OAuth** — add `https://dev.jinemi.com/user/oauth2/<name>/callback`
|
||||
as an authorized redirect URI in the Google Cloud console *before* the flip.
|
||||
Not in this repo; nothing here can verify it. Miss it and no one can log in,
|
||||
including to undo the flip.
|
||||
2. **The registry host in image names** — images are named by registry host, and
|
||||
the `git.thermograph.org/` prefix is baked into the runner labels
|
||||
(`register-lan-runner.sh`, `runner-vps2/README.md`), the CI-runner image
|
||||
(`ci-runner/Dockerfile`), `REGISTRY_HOST` in `infra/.env.example`, and every
|
||||
already-pushed tag. Renaming the registry host is a separate migration from
|
||||
renaming the web UI; the two need not happen together, and doing the web UI
|
||||
alone is much the smaller change.
|
||||
3. **Mesh `/etc/hosts` pins** — every node in "Registry access from mesh
|
||||
clients" below pins `git.thermograph.org` to `10.10.0.2`. A node pulling
|
||||
under a new hostname needs its own pin, or Caddy's `/v2/*` matcher sees a
|
||||
public source IP and returns 403.
|
||||
4. **Runner instance URL** — registered runners hold the instance URL they were
|
||||
registered with. Existing runners keep working against the old name as long
|
||||
as it resolves; a *re*-registration must use whichever name is canonical then.
|
||||
https://dev.jinemi.com/user/oauth2/google/callback
|
||||
https://git.thermograph.org/user/oauth2/google/callback
|
||||
|
||||
Until all four are handled, leaving `ROOT_URL` on `git.thermograph.org` is the
|
||||
correct state, not an unfinished one.
|
||||
Verify rather than assume. Google answers this with no credentials: a
|
||||
registered URI serves the sign-in page, an unregistered one returns
|
||||
`redirect_uri_mismatch`. Substitute the host you intend to make canonical:
|
||||
|
||||
```sh
|
||||
CID=337247886376-4360kepi20f24pue62ptg0lnqhcht46l.apps.googleusercontent.com
|
||||
curl -sL "https://accounts.google.com/o/oauth2/v2/auth?client_id=$CID&redirect_uri=https%3A%2F%2F<host>%2Fuser%2Foauth2%2Fgoogle%2Fcallback&response_type=code&scope=openid+email+profile&state=probe" \
|
||||
| grep -q redirect_uri_mismatch && echo REJECTED || echo ACCEPTED
|
||||
```
|
||||
|
||||
The stack has **no auto-deploy**: a `FORGEJO_DOMAIN` change here only takes
|
||||
effect when someone re-runs `docker stack deploy` by hand on the manager (vps2)
|
||||
— see "Deploy / update" above. Until then the running service keeps whatever
|
||||
`ROOT_URL` it was last deployed with, regardless of what this file says.
|
||||
|
||||
## Registry access from mesh clients
|
||||
|
||||
|
|
|
|||
|
|
@ -14,15 +14,16 @@
|
|||
# both. Splitting dev.jinemi.com into its own block serves the same Forgejo
|
||||
# with the registry API open to the public internet.
|
||||
#
|
||||
# dev.jinemi.com is the migration target for git.thermograph.org; both are
|
||||
# served during the transition. Each gets its own Let's Encrypt cert
|
||||
# automatically (HTTP-01) — both A records already point at vps1.
|
||||
# dev.jinemi.com is CANONICAL — it is Forgejo's ROOT_URL (docker-stack.yml,
|
||||
# FORGEJO_DOMAIN), so it is the name Forgejo puts in clone URLs, the OAuth
|
||||
# callback, webhook payload URLs and mail links.
|
||||
#
|
||||
# git.thermograph.org stays CANONICAL until Forgejo's ROOT_URL is flipped
|
||||
# (docker-stack.yml, FORGEJO_DOMAIN). Until then dev.jinemi.com serves every
|
||||
# page, but Forgejo builds absolute URLs from ROOT_URL, so clone URLs, the
|
||||
# OAuth callback and post-login redirects still name git.thermograph.org.
|
||||
# Flipping it is NOT just this file — see README.md, "Migrating the domain".
|
||||
# git.thermograph.org is kept as a served alias, NOT as dead weight: the
|
||||
# registry host baked into image names, the mesh /etc/hosts pins and the
|
||||
# runners' registered instance URL all still say git.thermograph.org. Removing
|
||||
# this name from the block breaks CI, not just old bookmarks. Both names get
|
||||
# their own Let's Encrypt cert automatically (HTTP-01); both A records point
|
||||
# at vps1. See README.md, "Migrating the domain".
|
||||
#
|
||||
# Registry exposure (hazard #15, see docker-stack.yml's header comment):
|
||||
# /v2/* is the built-in OCI registry API. It's blocked from anywhere except
|
||||
|
|
|
|||
|
|
@ -80,8 +80,25 @@ services:
|
|||
FORGEJO__database__HOST: db:5432
|
||||
FORGEJO__database__NAME: forgejo
|
||||
FORGEJO__database__USER: forgejo
|
||||
FORGEJO__server__DOMAIN: "${FORGEJO_DOMAIN:-git.thermograph.org}"
|
||||
FORGEJO__server__ROOT_URL: "https://${FORGEJO_DOMAIN:-git.thermograph.org}/"
|
||||
# Canonical domain. Forgejo has exactly ONE ROOT_URL and derives every
|
||||
# absolute URL from it — clone URLs, the Google OAuth callback, webhook
|
||||
# payload URLs, mail links. git.thermograph.org is still served (Caddy
|
||||
# answers for both names off one site block, deploy/forgejo/caddy-git.conf)
|
||||
# and still works for browsing, git-over-HTTP and the API; it is simply no
|
||||
# longer the name Forgejo generates.
|
||||
#
|
||||
# Changing this breaks login unless the matching redirect URI exists on
|
||||
# the Google OAuth client FIRST — login is SSO-only, so a mismatch locks
|
||||
# everyone out of the UI, including out of the ability to undo it. Both
|
||||
# https://dev.jinemi.com/user/oauth2/google/callback and the
|
||||
# git.thermograph.org one are registered; verify with a probe before
|
||||
# changing this again (deploy/forgejo/README.md, "Migrating the domain").
|
||||
#
|
||||
# NOT changed by this: the registry host baked into image names, the mesh
|
||||
# /etc/hosts pins, and the runners' registered instance URL all still say
|
||||
# git.thermograph.org. That is a separate migration.
|
||||
FORGEJO__server__DOMAIN: "${FORGEJO_DOMAIN:-dev.jinemi.com}"
|
||||
FORGEJO__server__ROOT_URL: "https://${FORGEJO_DOMAIN:-dev.jinemi.com}/"
|
||||
FORGEJO__server__SSH_PORT: "2222"
|
||||
# Without this, Forgejo starts no SSH server at all despite SSH_PORT
|
||||
# being set — git@ clones get "connection refused", not a slow failure.
|
||||
|
|
|
|||
Loading…
Reference in a new issue