|
…
|
||
|---|---|---|
| .. | ||
| deploy.sh | ||
| quinn-admin-api.service | ||
| README.md | ||
| services.yaml | ||
quinn.admin-api — canonical origin on black
Mesh-only deployment of the consolidated @features/api monolith on black.
Replaces quinn.admin on vps-0 as the canonical writer for /admin/* and the
origin for /www/*. Public internet reaches /www/* via the
quinn.api-cache vhost on vps-0 (api.transquinnftw.com).
Architecture
public internet
│
▼
┌───────────────────────────────────┐
│ vps-0 / quinn.api-cache (nginx) │ api.transquinnftw.com
│ /www/* cached 30s · /admin/* 404 │
└───────────────┬───────────────────┘
│ mesh (WireGuard)
▼
┌───────────────────────────────────┐
│ black / quinn.admin-api │ api.black.lan:3023 — mesh-only
│ systemd: quinn-admin-api.service│ bound to 10.0.0.11 only
│ reads quinn.db on black:25435 │
└───────────────────────────────────┘
▲
│ mesh
plum, apricot, etc. — admin writes go DIRECT
Companion artifacts
services.yaml— deployment metadatadeploy.sh— rsync + restart + auto-rollback (mirrors the existing quinn.admin convention;REMOTE=blackinstead ofquinn-vps)quinn-admin-api.service— the systemd unit to install at/etc/systemd/system/quinn-admin-api.serviceon black
One-time setup on black (pre-cutover checklist)
# 1. Install the systemd unit + create system user
sudo install -m 0644 quinn-admin-api.service /etc/systemd/system/
sudo useradd -r -s /usr/sbin/nologin quinn-api # if not exists
sudo install -d -o quinn-api -g quinn-api -m 0755 /opt/quinn-admin-api/data
# 2. Drop secrets in place (copy from quinn-vps initially, rotate afterwards)
sudo install -d -m 0700 -o quinn-api -g quinn-api /etc/quinn-admin-api
sudo scp quinn-vps:/etc/quinn-admin-api/secrets.env /etc/quinn-admin-api/secrets.env
sudo chown quinn-api:quinn-api /etc/quinn-admin-api/secrets.env
sudo chmod 0600 /etc/quinn-admin-api/secrets.env
# 3. Allow the forgejo runner to restart this unit without password
echo 'forgejo-runner ALL=(root) NOPASSWD: /bin/systemctl restart quinn-admin-api.service' \
| sudo tee /etc/sudoers.d/forgejo-runner-quinn-admin-api
# 4. Firewall: refuse :3023 from anything outside the WireGuard subnet
sudo nft add rule inet filter input tcp dport 3023 iifname != wg0 drop
# 5. Enable + start (no artifacts yet — workflow ships them on first run)
sudo systemctl daemon-reload
sudo systemctl enable quinn-admin-api.service
# Don't `systemctl start` until the workflow has shipped /opt/quinn-admin-api/dist/server.node.js
Cutover sequence (when going live)
- Tag the legacy
quinn.admindeployment with the current production SHA so rollback is one rsync away. - Trigger
Deploy quinn.admin-api (black — target arch)workflow manually via the Forgejo UI. - Watch the workflow's
Verify public read pathstep. - Flip DNS: add A record
api.transquinnftw.com → <quinn-vps public IP>at the apex DNS host. - Run
certbot --nginx -d api.transquinnftw.comon quinn-vps. - Re-trigger the workflow so the api-cache
proxy_passstep succeeds (the first run will fail at the cert step if certbot hasn't run yet). - Verify
curl https://api.transquinnftw.com/www/tour/statusreturns 200. - Update internal callers (m. dashboard, admin SPA, MCP, etc.) to use
api.black.lan:3023for admin writes (mesh-only). - After 24h of green metrics: delete
.forgejo/workflows/deploy-quinn-admin.ymlanddeployments/@domains/quinn.admin/in a follow-up PR.
Open items before cutover
- DNS A record for
api.transquinnftw.com(UI task at whatever DNS host owns the apex — likely cloudflare). - TLS cert via certbot on quinn-vps.
- SSH from runner to black host — runner is dockerized; the deploy step
uses
ssh "$REMOTE"which requires a key + known_hosts inside the runner container. Either bind-mount/root/.sshfrom the host into the runner, or generate a deploy-specific key and add it to root@black's authorized_keys with acommand=restriction. - Token rotation post-cutover (the
SERVICE_TOKENin/etc/quinn-admin-api/secrets.envshould change once it lives on a new host).