Deploy to monsterrobot.games/paradramorama

Games-lander pattern: rsync to the host path (RO bind mount into
forum-nginx, docker cp fails silently) + top-level symlink for the pretty
URL, no nginx change. Stamps a version query across the ES-module chain in
a staging copy because Cloudflare serves .js with max-age=14400 — without
it a redeploy shows stale code for hours.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
m3ultra 2026-07-26 10:38:10 +10:00
parent 21dd748e8e
commit 97a4a01b0b
2 changed files with 83 additions and 2 deletions

View File

@ -9,9 +9,12 @@ world does not pause), wear its body while it decays, burn its weapons, and bail
before it blows. Purge every amp and every machine on the floor and the drone
resolves to a chord.
## Run it
## Play it
Any static server from the repo root (ES modules won't load off `file://`):
Live: **https://monsterrobot.games/paradramorama/**
Locally — any static server from the repo root (ES modules won't load off
`file://`):
```
python3 -m http.server 8474
@ -19,6 +22,23 @@ python3 -m http.server 8474
then open http://localhost:8474
## Deploy
```
./deploy/deploy.sh
```
Rsyncs to the games VPS (`humanjing@100.71.119.27`) at
`/home/humanjing/monsterrobot.games/games/paradramorama/` — a **read-only**
bind mount into `forum-nginx`, so deploys write the host path (`docker cp`
fails silently). Needs no nginx change; the apex server block serves any
subdirectory, and a top-level symlink gives the pretty URL.
Cloudflare serves `.js` with a 4-hour `max-age`, so the deploy stamps a
version query across the whole module chain (`index.html` → `game.js`
`world.js`/`audio.js`) in a staging copy. Source files are never touched.
Without that you would test stale code for hours after a redeploy.
## Controls
| Key | Action |

61
deploy/deploy.sh Executable file
View File

@ -0,0 +1,61 @@
#!/usr/bin/env bash
# Deploy PARADRAMORAMA to monsterrobot.games/paradramorama (botchat/games VPS).
#
# The apex monsterrobot.games is a STATIC LANDING on humanjing@100.71.119.27:
# host /home/humanjing/monsterrobot.games -> forum-nginx
# /usr/share/nginx/html/games-lander (READ-ONLY bind mount)
# `docker cp` into the container FAILS SILENTLY because the mount is RO —
# always write to the host path, nginx serves it live.
#
# Routing needs NO nginx change: the apex server block ends in
# location / { try_files $uri $uri/ /index.html; }
# so any directory under the root is served directly. Games live in
# games/<name>/ with a top-level symlink for the pretty URL (same as
# mollycool, not-tonight).
#
# CACHE: Cloudflare fronts this domain and serves .js with max-age=14400 (4h).
# Without busting, a redeploy shows STALE CODE for hours. So the deploy stamps
# a version query onto the whole ES-module chain (index.html -> game.js ->
# world.js/audio.js) in a staging copy. Source files are never modified.
#
# Usage: ./deploy/deploy.sh
set -euo pipefail
VPS="humanjing@100.71.119.27"
LANDER="/home/humanjing/monsterrobot.games"
NAME="paradramorama"
SRC="$(cd "$(dirname "$0")/.." && pwd)"
URL="https://monsterrobot.games/${NAME}/"
STAMP="$(cd "$SRC" && git rev-parse --short HEAD 2>/dev/null || echo nogit)-$(date +%s)"
BUILD="$(mktemp -d /tmp/paradramorama_build_XXXXXX)"
trap 'rm -rf "$BUILD"' EXIT
echo "→ staging build ($STAMP)"
rsync -a --exclude '.git' --exclude '.gitignore' --exclude 'deploy' \
--exclude '.DS_Store' "$SRC/" "$BUILD/"
# stamp the module chain so Cloudflare + the browser always fetch fresh code
perl -pi -e "s{src=\"src/game\.js\"}{src=\"src/game.js?v=$STAMP\"}g" "$BUILD/index.html"
perl -pi -e "s{from '\./(world|audio)\.js'}{from './\$1.js?v=$STAMP'}g" "$BUILD/src/game.js"
grep -q "game.js?v=$STAMP" "$BUILD/index.html" || { echo "✗ stamp failed (index.html)"; exit 1; }
grep -q "world.js?v=$STAMP" "$BUILD/src/game.js" || { echo "✗ stamp failed (game.js imports)"; exit 1; }
echo "→ rsync → $VPS:$LANDER/games/$NAME/"
ssh "$VPS" "mkdir -p '$LANDER/games/$NAME'"
rsync -az --delete "$BUILD/" "$VPS:$LANDER/games/$NAME/"
echo "→ ensure pretty-URL symlink $LANDER/$NAME -> games/$NAME"
ssh "$VPS" "cd '$LANDER' && ln -sfn 'games/$NAME' '$NAME' && ls -ld '$NAME'"
echo "→ verifying live"
CB="$(date +%s)"
CODE=$(curl -sS -o /dev/null -w '%{http_code}' -L "${URL}?cb=${CB}" --max-time 25)
JS=$(curl -sS -o /dev/null -w '%{http_code}' -L "${URL}src/game.js?v=${STAMP}" --max-time 25)
SERVED=$(curl -sS -L "${URL}?cb=${CB}" --max-time 25 | grep -o "game\.js?v=[^\"]*" | head -1)
echo " index: $CODE game.js: $JS serving: $SERVED"
if [ "$CODE$JS" = "200200" ] && [ "$SERVED" = "game.js?v=$STAMP" ]; then
echo "✓ live at $URL"
else
echo "✗ NOT deployed cleanly (index=$CODE js=$JS served=$SERVED)"; exit 1
fi