diff --git a/plan/14-deploy.md b/plan/14-deploy.md index ffb9c29..cb9d9dd 100644 --- a/plan/14-deploy.md +++ b/plan/14-deploy.md @@ -14,48 +14,55 @@ Production host for the Ulicraft stack. ## Routine redeploy -```bash -ssh cochi -cd /home/ubuntu/mc/ulicraft-server-v1 -git pull --ff-only -tooling/render-config.sh # re-render drasl/nmsr configs from .env -tooling/sync-server-mods.sh # sync ./server-mods from $DISTRIBUTION_WEB_ROOT -docker compose down --remove-orphans -docker compose up -d --build -``` +`update-all.sh` (repo root) is the **single source of truth** for the post-pull +build + restart steps. Run it AFTER a `git pull` (it never pulls or pushes). +Strict halt on any error — never a partial deploy. -Or as a one-shot from your workstation: +Two modes: + +- `./update-all.sh` — **rolling**: `docker compose up -d --build`, then restart + ONLY the services whose mounted inputs changed since a pre-run snapshot + (drasl/nmsr on a config re-render, minecraft on a mod change). Minimal + downtime. Does **not** detect caddy static-conf (`caddy/conf.d/*.caddy`) + changes — use `--hard` for those. +- `./update-all.sh --hard` — `docker compose down --remove-orphans && up -d + --build`. Full restart (Minecraft world downtime); picks up everything. + +One-shot full redeploy from your workstation (the `deploy` skill does exactly +this): ```bash ssh cochi 'set -e cd /home/ubuntu/mc/ulicraft-server-v1 git pull --ff-only - tooling/render-config.sh - tooling/sync-server-mods.sh - docker compose down --remove-orphans - docker compose up -d --build' + tooling/fetch-authlib.sh # ensure authlib jar (rarely changes; NOT in update-all) + ./update-all.sh --hard' ``` -`render-config.sh` re-renders the drasl/nmsr configs from `.env`; -`sync-server-mods.sh` mirrors the `both`/`server` mod subset (from -`mods-sides.json`) out of `$DISTRIBUTION_WEB_ROOT` into `./server-mods` before -the stack comes back up. `$DISTRIBUTION_WEB_ROOT` must resolve on the host (it -also backs the caddy `distribution.` mount). - -### Landing rebuild (not part of `compose`) - -The landing site (incl. `/register`) is static `www/`, gitignored — a `git pull` -does **not** update it. Rebuild on the host whenever `landing/` changed or you -toggled `REGISTRATION_MODE` (it bakes the invite-field on/off at build, and Drasl's -`RequireInvite` is derived from the same key by `render-config.sh`): +Everyday landing/config tweak (no world downtime): ```bash -( cd landing && set -a && . ../.env && set +a && pnpm run build ) # → www/ -docker compose restart drasl # apply CORS / RateLimit / RequireInvite +ssh cochi 'cd /home/ubuntu/mc/ulicraft-server-v1 && git pull --ff-only && ./update-all.sh' ``` -`down`/`up` is not needed for a landing-only or flag-only change — rebuild `www/` -and restart `drasl`. +Steps `update-all.sh` runs, in order: `render-config.sh` (drasl/nmsr from `.env`; +halts on a bad `REGISTRATION_MODE`) → `sync-server-mods.sh` (mirror the +`both`/`server` subset from `mods-sides.json` out of `$DISTRIBUTION_WEB_ROOT` +into `./server-mods`) → `build-modlist.py` (regen landing `mods.json` + logos; +**run under `python>=3.11`** — cochi's default `python3` is 3.10, but +`python3.11` is installed and the script auto-selects it) → landing `pnpm build` +(sources nvm + `.env`, never `npm`) → docker compose. `$DISTRIBUTION_WEB_ROOT` +must resolve on the host (it also backs the caddy `distribution.` mount). + +### Landing site + mod list (generated, not in git) + +Both the static site `www/` AND the landing `mods.json` are gitignored — a `git +pull` never updates them. `update-all.sh` regenerates both every run +(`mods.json` via `build-modlist.py`, `www/` via `pnpm build`). A flag-only +`REGISTRATION_MODE` change just needs a rolling `./update-all.sh`: it rebuilds +`www/` (bakes the invite-field on/off) and restarts `drasl` only if +`render-config.sh` changed its config (Drasl's `RequireInvite`/CORS/RateLimit) — +no world downtime. ## Known host-local divergence on `cochi` (uncommitted)