Files
wizwar6e/deploy/setup-droplet.sh
T
Eric WagonerandClaude Fable 5.1 c7edfa74ad The state is copied by hand, and the proxy waits out a restart
Two-thirds of a ledger replay was structuredClone; a recursive copy of
plain data does the same work in a fraction of the time, so a server
boot — every ledger replayed — is half as long, and the automaton's
lookahead is quicker with it. Caddy now holds a request for up to
thirty seconds while the game restarts, dialing every quarter second,
so a visitor who lands during a deploy waits instead of meeting a 502.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Jm2auWk6RP71CjaAb4FMoG
2026-09-05 20:41:02 -04:00

43 lines
1.9 KiB
Bash
Executable File

#!/usr/bin/env bash
# One-time droplet setup. Run ON the droplet as root:
# bash setup-droplet.sh wizwar.<droplet-ip>.sslip.io
set -euo pipefail
HOST="${1:?usage: setup-droplet.sh <hostname>}"
apt-get update -q
apt-get install -qy curl git rsync
# Node 22
curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
apt-get install -qy nodejs
# Caddy (auto-HTTPS)
apt-get install -qy debian-keyring debian-archive-keyring apt-transport-https
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' \
| gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' \
| tee /etc/apt/sources.list.d/caddy-stable.list
apt-get update -q && apt-get install -qy caddy
# App user + directories
id -u wizwar &>/dev/null || useradd -r -m -d /opt/wizwar-home wizwar
mkdir -p /opt/wizwar /var/lib/wizwar/rooms
chown -R wizwar:wizwar /opt/wizwar /var/lib/wizwar
# Caddy vhost: auto-TLS, security headers, proxy to the game.
# Access log kept to 30 rolls of 10MiB: the nightly rollup keeps the
# counts; the raw lines back it for a while. A deploy restarts the game
# for a few seconds; the proxy holds requests that land in that gap and
# keeps dialing, so a visitor waits instead of meeting a 502.
printf '%s\n\nheader {\n\tStrict-Transport-Security "max-age=31536000"\n\tX-Content-Type-Options "nosniff"\n\tX-Frame-Options "DENY"\n\tReferrer-Policy "no-referrer"\n}\nlog {\n\toutput file /var/lib/caddy/access.log {\n\t\troll_size 10MiB\n\t\troll_keep 30\n\t}\n}\nreverse_proxy localhost:8787 {\n\tlb_try_duration 30s\n\tlb_try_interval 250ms\n}\n' "$HOST" > /etc/caddy/Caddyfile
systemctl reload caddy
# Firewall: ssh + web only. The game server binds loopback and is reached
# through Caddy; nothing else should answer the internet.
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable
echo "droplet ready — now run deploy.sh from your machine"