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:
parent
21dd748e8e
commit
97a4a01b0b
24
README.md
24
README.md
@ -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
|
before it blows. Purge every amp and every machine on the floor and the drone
|
||||||
resolves to a chord.
|
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
|
python3 -m http.server 8474
|
||||||
@ -19,6 +22,23 @@ python3 -m http.server 8474
|
|||||||
|
|
||||||
then open http://localhost: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
|
## Controls
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|
|||||||
61
deploy/deploy.sh
Executable file
61
deploy/deploy.sh
Executable 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
|
||||||
Loading…
Reference in New Issue
Block a user