Files
wizwar6e/deploy/README.md
T

67 lines
3.3 KiB
Markdown

# Deploying Wiz-War
The game runs on a single DigitalOcean droplet: one Node process serves the
built client and the websocket on port 8787; Caddy in front terminates TLS
with automatic certificates. Room files persist in /var/lib/wizwar/rooms and
survive deploys and reboots.
## Current production
- Host: `hall` (nyc3, tag `kestrels-hall`), IP 159.203.115.252, shared with
the other games of Kestrel's Hall since 2026-09-29; Wiz-War keeps its own
service user, port 8787, site file and access log there.
- URLs: https://wizwar.kestrelsnest.social
and https://wizwar.159.203.115.252.sslip.io (always works, zero DNS).
Caddy serves both; NOTE: kestrelsnest.social's authoritative DNS is at
HOVER (ns1/ns2.hover.com), not DigitalOcean — records must be added there.
A matching record also sits in the DO zone in case nameservers ever move.
## Everyday deploys
deploy/deploy.sh 159.203.115.252
Builds the client locally, rsyncs the repo (minus node_modules, data/, .git,
research), installs dependencies on the droplet, and restarts the service.
Games in progress survive: state lives in room files, and clients reconnect
automatically.
Before any deploy that touches the engine, run the determinism gate:
deploy/verify-ledgers.sh 159.203.115.252
It fetches every production ledger and strictly replays it against the local
engine; a single refused command fails the check. A room whose ledger no
longer replays becomes unreachable after restart, so this is not optional.
## New droplet from scratch
1. `doctl compute droplet create wizwar --region nyc3 --size s-1vcpu-1gb \
--image ubuntu-24-04-x64 --ssh-keys <your-key-ids> --tag-name wizwar --wait`
2. `scp deploy/setup-droplet.sh deploy/Caddyfile.tmpl root@<ip>:/root/ && ssh root@<ip> \
"bash /root/setup-droplet.sh 'wizwar.<ip>.sslip.io'"` (the host's Caddyfile
gathers each game's site from /etc/caddy/sites/, so the host can be shared)
3. `deploy/deploy.sh <ip>`
## Operations
- Logs: `ssh root@<ip> journalctl -u wizwar -f`
- Restart: `ssh root@<ip> systemctl restart wizwar`
- Nightly backups: `wizwar-backup.sh` runs from root's crontab at 07:17 UTC,
pushing /var/lib/wizwar to the `kestrel-wizwar-backups` Space (nyc3) via
rclone. It is installed at /usr/local/bin/wizwar-backup.sh on the droplet;
`setup-droplet.sh` does NOT install it — on a fresh droplet, copy the
script, configure rclone (the script refuses to run while the config still
holds its CHANGE_ME placeholder), and add the cron entry by hand.
- A player whose browser lost their seat (Safari's seven days, an app's own
browser, cleared data) writes to the keeper. On the droplet,
`wizwar-reseat.sh ROOM` lists who sits at the table and when each last
moved or spoke; `wizwar-reseat.sh ROOM NAME` gives that wizard's seat a new
token and prints a link carrying it in the fragment. The old token opens
nothing after. The script answers through the game server's keeper door,
a listener of its own on 127.0.0.1:9787 that Caddy never reaches, which
opens only to the key in /etc/wizwar/keeper.key (root and the wizwar user
alone can read it, so the other services on the host cannot use the door).
The first deploy makes the key, and every deploy installs the script at
/usr/local/bin.
- One-off backup: `scp -r root@<ip>:/var/lib/wizwar/rooms ./rooms-backup`