Files
wtclaude 38aef5964e
All checks were successful
PR Checks / bot-tests (pull_request) Successful in 47s
PR Checks / client-build (pull_request) Successful in 1m8s
PR Checks / server-tests (pull_request) Successful in 12m27s
feat(demo): seed the default set's NPC profiles, factions and chat titles (DM26)
The restored rig's RunicNPC says it is already managed, so a fresh site
adopts none of its profiles and its first push empties them; chat styles
are never adopted either. They come from the fixture now, through
Module-Rust's onDemoSeed (needs the release carrying DM26; an older module
ignores these keys):

- npcs.factions: bandits and guards, allied;
- npcs.profiles: bandit (roamer, rnpc_raider) and guard (sentry, heavy,
  rnpc_campguard, heals), both on the demo server. Only the fields that
  differ from RunicNPC's defaults are listed;
- chat: [VIP] in gold and [MOD] in green.

The baseline's placements (bandit-1, bandit-2, guard-1) spawn again once
the site pushes these.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
2026-10-27 20:16:27 -05:00
..

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.