docs: update deploy workflow — NAS now git pull, not manual FTP
Confirmed 2026-09-07 while deploying the Child Safety Standards page: /Dockers/PawFeed on the NAS is its own git checkout tracking the self-hosted Gitea remote, kept up to date via git pull rather than the manual FTP upload this file previously described. Documents the actual deploy steps (ssh daniel@192.168.1.222 on the standard port, git pull, then rolling-deploy.sh) so this doesn't need rediscovering next time.
This commit is contained in:
1 parent
4758ce8d87
commit
92d6495cc9
1 file changed
+3
-1
@@ -96,7 +96,9 @@ Vitest + `jsdom`. Prisma is fully mocked per-model via `createMockPrisma()` in `
|
||||
|
||||
### Deployment — self-hosted Docker, not Vercel
|
||||
|
||||
Despite `next.config.ts`'s `output: "standalone"` and the original stack research recommending Vercel, this app is deployed to a self-hosted OpenMediaVault NAS via Docker (`docker/Dockerfile`, `docker/docker-compose.yml`, `docker/start.sh`). **There is no `git pull` on the server** — deploys are manual FTP uploads of changed files followed by `./start.sh`. Don't suggest Vercel-specific features (ISR revalidation webhooks, Vercel KV, edge config) without checking this still holds.
|
||||
Despite `next.config.ts`'s `output: "standalone"` and the original stack research recommending Vercel, this app is deployed to a self-hosted OpenMediaVault NAS via Docker (`docker/Dockerfile`, `docker/docker-compose.yml`, `docker/start.sh`). Don't suggest Vercel-specific features (ISR revalidation webhooks, Vercel KV, edge config) without checking this still holds.
|
||||
|
||||
**Deploy sync is now `git pull` on the server, not manual FTP** (confirmed 2026-09-07 — supersedes the old FTP-based process; update this note again if it changes further). The NAS at `/Dockers/PawFeed` is its own git checkout with `origin` pointing at the self-hosted Gitea instance (`http://192.168.1.222:3666/admin/petfeed.git`, same repo `git push` in this dev environment goes to over SSH on port 2222). To deploy: `ssh daniel@192.168.1.222` (standard port 22, key-based — a *different* credential from the port-2222 Gitea git-shell key used for `git push`/`git pull` from a dev machine), then on the NAS: `cd /Dockers/PawFeed && git pull origin main`, then `cd docker && ./rolling-deploy.sh` (or `sh ./rolling-deploy.sh` if it's not executable). `mobile/` changes land in this same working tree too (it's one repo) but don't need a deploy — `.dockerignore` excludes it from the image build.
|
||||
|
||||
**Runs as 3 load-balanced replicas, not a single container (since 2026-08-16, Gitea #26).** `docker/docker-compose.yml` defines `pawfeed-1`/`pawfeed-2`/`pawfeed-3` (via the `x-pawfeed-common` YAML anchor) instead of one `pawfeed` service — Next.js standalone output is single-process (`node server.js`), so one container only ever used one CPU core regardless of how many the NAS has. A load test on 2026-08-15 hit a hard ceiling at ~60–65 req/sec with one core pegged at 133% while 3 cores sat idle; splitting into 3 replicas fixed it (confirmed via a follow-up load test showing ~100% CPU spread evenly across all three). Nginx Proxy Manager (container `nginx-app-1` on this NAS, admin UI at `192.168.1.222:81`) load-balances across them via a `least_conn` upstream block — that block lives in `/Docker-Data/nginxproxymanager/data/nginx/custom/http_top.conf` on the NAS host (an nginx `upstream {}` is only valid in the `http{}` context, which NPM's per-host "Custom Nginx Configuration" field can't reach — that field only writes into the `server{}`/`location{}` context, and holds the `proxy_pass http://pawfeed_upstream;` override for the `pawfeed.org` Proxy Host instead). Full runbook, decisions, and risk notes: `docker/SCALING-ROADMAP.md`. **Deploying a config or code change means rebuilding all 3 replicas** — there is no separate single-container path anymore, and NPM's proxy target is `pawfeed_upstream`, not a bare `pawfeed:3000` hostname. Use `./docker/rolling-deploy.sh` for deploys against the live site — it rebuilds the shared `pawfeed:latest` image once, then restarts `pawfeed-1`/`2`/`3` one at a time, gated on each becoming `healthy` per the Docker `healthcheck` (`GET /api/health`, a dependency-free liveness check — see `src/app/api/health/route.ts`) before moving to the next, so at least 2 replicas always serve traffic. Verified zero-downtime on 2026-08-16 (continuous curl monitoring showed unbroken HTTP 200 through a full rolling deploy). `docker compose up -d --build` (`start.sh`) still works but restarts all 3 at once — only use it for first-time setup or when a brief outage is acceptable. `src/lib/prisma.ts`'s Prisma pg pool size is capped per-replica via `DB_POOL_MAX` (compose sets `10`) so 3 replicas stay well under the Supabase pooler's client-connection limit.
|
||||
|
||||
|
||||
Reference in new issue
Block a user