Wiki Index
13 / 50 entity pages. Last regenerated: 2026-07-24. See SCHEMA.md for the entity-page contract and README.md for purpose, conventions, and authority — including § Tradeoffs .
All entity pages currently carry status: draft: the infra/
artifacts exist and are described accurately, but the migration has
not yet run against a production droplet (see
SCHEMA.md § Status Values
). The one exception is the
canonical migration hub, which cites only the plan.
Concept
Abstract ideas, contracts, and design decisions.
- Render-to-DigitalOcean Migration
— (canonical) the hub. Why
apps/server+ PostgreSQL + ewiki leave Render for one DigitalOcean droplet behind Cloudflare; the locked-decisions architecture, the honest cost-is-a-wash / control-is-the-driver read, the accepted single-box SPOF mitigated by tested R2 backups, and the Phase 0→7 sequence with Render kept warm as the rollback target.
Tutorial
Step-by-step procedures, each owning a runnable infra artifact.
Foundations — host provisioning & hardening (Phase 1)
- Provision Droplet
— owns
infra/cloud-init.yaml. First-boot bootstrap: the non-rootoperatoruser + authorized key, base apt packages, timezone, and the/etc/laanchor for the deploy.env. - SSH Hardening
— owns
infra/scripts/05-user-and-ssh.ps1. Key-only login via a managed sshd drop-in; disables root login and password auth, with the two-session anti-lockout sequence. - UFW Firewall
— owns
infra/scripts/06-ufw.ps1. Default-deny inbound; allow SSH + 80/443 (443 later narrowed to Cloudflare IPs by Cloudflare TLS ). - Fail2ban and Unattended Upgrades
— owns
infra/scripts/07-fail2ban-upgrades.ps1. SSH brute-force bans + automatic security patching — the patching responsibility you now own instead of Render.
Runtime (Phase 2)
- Node Runtime
— owns
infra/scripts/10-node.ps1. fnm at/opt/fnmpinning Node 24.18.0 and corepack/pnpm 10.32.1 to match.node-version.
Web — reverse proxy & edge (Phase 2)
- Nginx Reverse Proxy
— owns
infra/nginx/api.conf+infra/scripts/20-nginx.ps1. Proxiesapi.to127.0.0.1:3000with the WebSocket-upgrade headers Socket.IO needs; the plain-HTTP stage before TLS. - Cloudflare TLS
— owns
infra/scripts/21-cloudflare-tls.ps1. Origin Certificate + Full(strict), 80→443 redirect, and UFW 443 restricted to live Cloudflare IP ranges.
Data (Phase 2)
- PostgreSQL Setup
— owns
infra/scripts/30-postgres.ps1. Self-hosted PostgreSQL 18 on localhost, scram-sha-256, and 8 GB-box tuning; creates thelarole and database.
App & Ops — deploy (Phases 3–4)
- Deploy Server
— owns
infra/scripts/40-app-deploy.ps1infra/systemd/la-server.serviceinfra/.env.example. Clone/build via fnm, install + enable the systemd unit, restart, and health-check.
- Deploy Pipeline
— owns
.github/workflows/deploy.yml. GitHub Actions → SSH →git pull+ build + migrate +systemctl reload la-server, replacing Render’s push-to-main auto-deploy.
Guide
Reference explainers for a subsystem or contract without a single runnable script.
- Secrets and Env
— owns
infra/.env.example. The ~15sync:falsevariables (auth, Stripe, analytics tokens, R2, Brevo) as the environment contract; real values live only in/etc/la/.envat mode 600. - Systemd Service
— owns
infra/systemd/la-server.service. Thela-serverunit:ExecStartthrough fnm-pinned Node,EnvironmentFile,Restart=on-failure, and reboot survival — why systemd over PM2.
Pages by owning artifact
| Wiki page | Owning artifact(s) |
|---|---|
| Provision Droplet | infra/cloud-init.yaml |
| SSH Hardening | infra/scripts/05-user-and-ssh.ps1 |
| UFW Firewall | infra/scripts/06-ufw.ps1 |
| Fail2ban and Unattended Upgrades | infra/scripts/07-fail2ban-upgrades.ps1 |
| Node Runtime | infra/scripts/10-node.ps1 |
| Nginx Reverse Proxy | infra/nginx/api.conf, infra/scripts/20-nginx.ps1 |
| Cloudflare TLS | infra/scripts/21-cloudflare-tls.ps1 |
| PostgreSQL Setup | infra/scripts/30-postgres.ps1 |
| Deploy Server | infra/scripts/40-app-deploy.ps1, infra/systemd/la-server.service, infra/.env.example |
| Deploy Pipeline | .github/workflows/deploy.yml |
| Secrets and Env | infra/.env.example |
| Systemd Service | infra/systemd/la-server.service |
| Render-to-DigitalOcean Migration | (concept — cites docs/PLAN.md) |
Not yet documented
Pages land when their owning artifact exists in infra/. Planned by
PLAN.md §5
but not yet present, so
intentionally absent from this wiki:
backup-restore—infra/scripts/50-backup.ps1/51-restore.ps1(pg_dump → R2, restore drill)postgres-maintenance—infra/scripts/52-vacuum-reclaim.ps1monitoring—infra/scripts/60-monitor.ps1cutover/disaster-recovery— orchestration procedures