wiki/decisions/2026-06-30-github-vps-auto-deploy.md
ADR: GitHub to VPS auto-deploy for prism-hub (webhook then git pull)
Date: 2026-06-30 Status: Accepted (verified live)
Context
The published reports site (prism-hub) is served as static files from /opt/prism-hub on the VPS by
the on-box static proxy. Earlier, deploying a change meant a manual scp of each edited file. Slow,
error-prone, and easy to forget.
Decision
A GitHub webhook fires on push to origin/feat/prism-vps-hosting. It hits a small Node listener on
the VPS (prism-deploy-hook.service, HMAC-gated) which runs git pull in /opt/prism-hub. The push
goes live with no manual step.
Rationale
The webhook-pull model keeps VPS credentials off GitHub (no SSH key stored as a GH secret), unlike an
Actions-push approach. /opt/prism-hub is already a git checkout of the repo, so the listener only
needs a pull. It is the standard "Vercel-style on your own box" pattern.
Alternatives Considered
| Option | Why rejected |
|---|---|
| GitHub Actions SSH and push | Stores a deploy private key as a GH secret; more surface |
Cron git pull every minute |
Works but chatty and adds 1 to 60s lag; webhook is instant |
| Keep manual scp | The thing we are removing; forgettable and error-prone |
Consequences
- Verified end to end this session: a real push auto-pulled to the VPS within seconds, served live.
- Prod branch for the hub deploy is
feat/prism-vps-hosting(it had the content; main was behind). - Pieces on the VPS:
/opt/prism-deploy-hook/(hook listener),prism-deploy-hook.service(systemd, enabled), Caddy route to the loopback listener. Deploy never runsgit clean, so untracked files on the box are preserved. - Full runbook in memory
reference-prism-hub-autodeploy. - This is why every About-page edit this session went live by push alone. See 2026-06-30-about-splash-routing.