Files
website/deploy/demo/README.md
wtclaude d48d8c473c
All checks were successful
PR Checks / bot-tests (pull_request) Successful in 50s
PR Checks / client-build (pull_request) Successful in 57s
PR Checks / server-tests (pull_request) Successful in 12m25s
feat(demo): deploy/demo and the wipe + baseline workflows (step 5)
The public demo's deployment (docs/website/DEMO_MODE.md §7, §10 step 5):

- deploy/demo/docker-compose.yml: the app and its database only, DEMO_MODE
  on, a /status healthcheck, the fixture mounted for seed:demo, MODULES read
  from state/modules.env so the workflow never edits the .env with secrets.
- deploy/demo/.env.example: every variable the host needs, including
  BOT_INTERNAL_KEY (the app refuses to start in production without it) and
  MODULE_SOURCE_HOSTS (a fresh database's install allowlist).
- deploy/demo/seed.json: the four logins, settings, two posts, a wiki page,
  a published "Server greeting" event on a Rust console step, the rig's
  server link and demo-player's Steam link; secrets as "$env:NAME".
- deploy/demo/rig.mjs: plan (latest Rust bundle + newest Module-Rust on the
  same protocol, keeping the previous set when none matches), restore (kill,
  write a changed bundle, delete + unpack demo-baseline.tar.gz, start),
  baseline (power stop saves the world, DM22; compress, rename, start) and
  smoke (the site, then the rig reporting in), on the Pterodactyl client API.
- .gitea/workflows/demo-wipe.yml: every 2 h on the hour UTC, on a push to
  deploy/demo/, and by hand; rig first, then down -v / pull / up / seed.
- .gitea/workflows/demo-baseline.yml: by hand only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-26 12:23:52 -05:00

54 lines
3.1 KiB
Markdown

# deploy/demo — demo.runicgateway.com
The public demo site: the normal image with `DEMO_MODE=true`, wiped every two hours together
with its Rust server. Design of record: `docs/website/DEMO_MODE.md`.
| File | What it is |
| --- | --- |
| `docker-compose.yml` | The app and its database. No bot and no ntfy: the demo sends nothing outward (§5) |
| `.env.example` | Every variable the host's `.env` needs, with what each one is for |
| `seed.json` | The fixture `seed:demo` writes after every wipe: the four logins, settings, content, and the Rust module's server link and Steam link (§7.3). Passwords and credentials are `"$env:NAME"` references to `.env` |
| `rig.mjs` | Versions (`plan`), the rig restore (`restore`), the baseline capture (`baseline`) and the smoke check (`smoke`), against the Pterodactyl client API (§7.2, §7.5) |
Two workflows drive it, both on the `demo-site` runner:
- **`demo-wipe.yml`**: every 2 hours on the hour (UTC), on a push to `main` that changes this
directory, and by hand. Versions, then the rig, then the site, then a smoke check.
- **`demo-baseline.yml`**: by hand only. It captures the rig's current state as
`demo-baseline.tar.gz`, which every wipe restores.
## One-time host setup
1. The `demo-site` runner in **host mode** on the demo host, with Docker and Compose, and `node`
on the `PATH` (for `actions/checkout`). The host must reach `gitea.whitlocktech.com`, the
Pterodactyl panel and the rig's sidecar port.
2. `sudo mkdir -p /opt/demo.runicgateway.com`, owned by the runner's user (or the runner runs as
root). To use another path, set the `DEMO_DIR` Actions variable.
3. Copy `.env.example` to `/opt/demo.runicgateway.com/.env` and fill every blank. Generate
secrets on the host, e.g. `openssl rand -hex 32`. The file never leaves the host.
4. Log the host in to the registry if the images are not public: `docker login gitea.whitlocktech.com`.
5. Point the external reverse proxy at `<host>:DEMO_HOST_PORT` (default 3000).
6. Run **Demo wipe** by hand. The first run finds no baseline, so it leaves the rig as it is and
starts it.
Then set the demo default set up through the site: the permission groups, a few NPCs, a clan. Run
**Demo baseline** while nobody else is changing anything. Every later wipe returns the rig to that.
The panel URL and the rig's server identifier default to `http://192.168.0.12` and `6eb9d621`
(`rust-oxide`). Override them with the `PTERODACTYL_URL` and `PTERODACTYL_SERVER` Actions
variables. `PTERODACTYL_CLIENT_KEY` is the demo subuser's key, an Actions secret.
## What the wipe keeps on the host
`state/` in the deploy directory:
- `bundle.json`: the Rust bundle last written onto the rig. A new bundle is written only when
this differs.
- `modules.env`: `MODULES=rust@<version>=<manifest>`, the newest Module-Rust release on the bundle's
protocol. When no release matches a new bundle yet, the wipe keeps this file and the rig's
bundle as they were and warns (§7.5).
- `plan.json`: this cycle's decision, from `plan` to `restore`.
`modules/` keeps the unpacked module between wipes. `down -v` drops the database and the uploads,
never this directory.