The home page is a centred card: title and pitch, your name, play the bot or continue the duel under way, create or join a duel by code, a sample ledger, the duels this browser holds with whose move it is, and the story of the game. The single-player board lives at /play. The droplet gains the duel server as a systemd service behind Caddy. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
66 lines
3.0 KiB
Markdown
66 lines
3.0 KiB
Markdown
# Deploying Waving Hands
|
|
|
|
The single-player game runs entirely in the browser. Duels between people
|
|
go through a small Node process that keeps each room as an append-only
|
|
ledger of moves in /var/lib/waving-hands/rooms. Production is one
|
|
DigitalOcean droplet: Caddy terminates TLS with automatic certificates,
|
|
serves the static build from /opt/waving-hands/build, and proxies /api and
|
|
/ws to the duel server on port 8788, which runs as the `waving-hands` user
|
|
under systemd from /opt/waving-hands/app.
|
|
|
|
## Sizing
|
|
|
|
The smallest droplet, `s-1vcpu-512mb-10gb` ($4 a month), carries both Caddy
|
|
and the duel server comfortably: the server is one small Node process capped
|
|
at 300 MB by its unit file, and a room is a few kilobytes of ledger.
|
|
|
|
The zero-cost alternative is a second site block in an existing Caddy
|
|
server's configuration pointing at a second directory; the deploy script
|
|
works unchanged against that host. A droplet of its own keeps this site's
|
|
uptime and upgrades independent of anything else.
|
|
|
|
## Current production
|
|
|
|
- Droplet: `waving-hands` (nyc3, s-1vcpu-512mb-10gb, tag `waving-hands`), IP 159.203.98.71
|
|
- URLs: https://hands.kestrelsnest.social (A record at Hover, where
|
|
kestrelsnest.social's DNS lives) and https://waving-hands.159.203.98.71.sslip.io
|
|
(always works, zero DNS). Caddy serves both from the first line of
|
|
/etc/caddy/Caddyfile.
|
|
- Everyday deploy: `deploy/deploy.sh 159.203.98.71`
|
|
|
|
## New droplet from scratch
|
|
|
|
1. `doctl compute droplet create waving-hands --region nyc3 \
|
|
--size s-1vcpu-512mb-10gb --image ubuntu-24-04-x64 \
|
|
--ssh-keys <your-key-ids> --tag-name waving-hands --wait`
|
|
2. `scp deploy/setup-droplet.sh root@<ip>:/root/ && ssh root@<ip> \
|
|
"bash /root/setup-droplet.sh 'hands.kestrelsnest.social, waving-hands.<ip>.sslip.io'"`
|
|
(point the A record at the new IP first, or leave the real name out until it is).
|
|
3. `scp deploy/setup-server.sh root@<ip>:/root/ && ssh root@<ip> "bash /root/setup-server.sh"`
|
|
4. `deploy/deploy.sh <ip>`
|
|
|
|
The sslip.io hostname works with no DNS at all. To add a real name, point an
|
|
A record at the droplet and add the name to the first line of
|
|
/etc/caddy/Caddyfile (space separated), then `systemctl reload caddy`; Caddy
|
|
fetches the certificate on first request.
|
|
|
|
## Everyday deploys
|
|
|
|
deploy/deploy.sh <ip>
|
|
|
|
Runs the type-checks, the tests and the build locally, rsyncs `build/` to
|
|
the droplet keeping the previous week's hashed assets, rsyncs the server and
|
|
engine sources, installs dependencies, and restarts the duel server. A
|
|
single-player game is in the player's own browser and loses nothing. A room
|
|
is replayed from its ledger when the server comes back, which takes a few
|
|
seconds; Caddy holds requests that land in the gap.
|
|
|
|
## Operations
|
|
|
|
- Logs: `ssh root@<ip> journalctl -u waving-hands -f` for the duel server,
|
|
`journalctl -u caddy -f` and /var/lib/caddy/access.log for the web side.
|
|
- Restart: `ssh root@<ip> systemctl restart waving-hands`
|
|
- Rooms: `/var/lib/waving-hands/rooms/<CODE>.jsonl`, one ledger per duel.
|
|
Copy that directory to back them up; single-player games are in players'
|
|
browsers.
|