Add VPS deployment runbook and provisioning script - #224
Open
mnindrazaka wants to merge 1 commit into
Open
Conversation
Adds infra-as-reviewed-text for the gatherloop-api VPS: an idempotent provision.sh (users, filesystem layout, systemd unit, sudoers grant, env template, ufw, Caddy), the systemd unit, sudoers drop-in, Caddyfile and env file templates, and the operator runbook (provisioning, secret rotation, logs, manual rollback, and the manual migration/seed procedures). No CI deploy wiring and no production traffic change yet — see docs/trd-vps-deployment-automation.md Phase 3.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds comprehensive documentation and automation for provisioning and operating the VPS that runs
apps/apiin production. It includes an operational runbook, an idempotent provisioning script, and all necessary configuration templates for systemd, environment variables, firewall, and reverse proxy setup.Key Changes
docs/runbook-vps-deployment.md: Complete operational reference covering:deploy/vps/provision.sh: Idempotent, re-runnable provisioning script that:gatherloop(runtime) anddeploy(CI) Unix users with appropriate permissions/opt/gatherloop-apirelease directory structuregatherloop-releaseandgatherloop-rollback)deploy/vps/systemd/gatherloop-api.service: Systemd unit with:gatherloopuser/etc/gatherloop-api/api.env(readable only by root and gatherloop)deploy/vps/env/api.env.example: Template for application secrets (DB credentials, JWT secret, logging config)deploy/vps/sudoers/gatherloop-deploy: Sudoers drop-in grantingdeployuser exactly two commands, both NOPASSWDdeploy/vps/caddy/Caddyfile.example: Reverse proxy template for TLS termination and proxying to127.0.0.1:8000Notable Implementation Details
Security model: The
deployuser (SSH target for CI) owns the release directory but cannot read secrets. Thegatherloopuser runs the API and is the only user that can read/etc/gatherloop-api/api.env. A compromised deploy key grants code execution as an unprivileged user with no database credentials in reach.Idempotent provisioning: The script safely re-runs after repo changes. It never overwrites existing secrets or customized Caddyfile, but will update managed files (systemd unit, sudoers, firewall rules) if the repo versions change.
Manual database migrations: By design, migrations are never run by the deploy pipeline. Operators run them by hand using the version-matched
migratebinary shipped in each release, viasystemd-runas thegatherloopuser so credentials come from the env file.Firewall isolation: Port 8000 (API's actual listen port) is unreachable from outside the box; only Caddy on the VPS can reach it, enforced by ufw.
https://claude.ai/code/session_01FkT3ro6MVgFZBuQZs5sNJ7