# Life Journey — Deployment Shell (Phase 0) An empty, deployable shell for the async multiplayer board game. It contains no game logic yet — its only job is to prove the deployment path works: the server runs in Docker, is reachable through Nginx Proxy Manager over HTTPS, and WebSockets survive the reverse proxy. Once both checks are green, adding the real game (Phase 1 onward) never touches the deployment story again. ## What's here ``` lifegame/ ├── docker-compose.yml ├── Dockerfile ├── package.json / package-lock.json ├── server/index.js # health endpoint + WebSocket echo └── public/index.html # live HTTP + WebSocket status page ``` ## 1. Put it on the homelab Drop the folder in your services directory (e.g. `~/homelab/lifegame/`) and build: ```bash cd ~/homelab/lifegame docker compose up -d --build docker compose logs -f # expect: "Life Journey (Phase 0) listening on :3000" ``` Verify locally on the host first: ```bash curl http://localhost:3000/api/health # {"ok":true,"service":"life-journey","phase":0,...} ``` ## 2. Point Nginx Proxy Manager at it Add a **Proxy Host**: - **Domain**: your chosen name, e.g. `game.example.com` - **Scheme**: `http` - **Forward Hostname / IP**: - *Option A (default compose):* the homelab's LAN IP (e.g. `192.168.x.x`) - *Option B (shared network):* `lifegame` - **Forward Port**: `3000` - **Websockets Support**: **ON** ← the easy-to-forget one - **SSL tab**: request a new Let's Encrypt certificate, Force SSL on ## 3. Confirm it works Open `https://game.example.com`. You should see two rows go green: - **Server (HTTP)** — the health endpoint responded - **WebSocket** — a live socket connected through the proxy Click **Send WebSocket ping** and the status should show the echo came back. If HTTP is green but WebSocket is red, the proxy isn't upgrading the connection — go back and toggle **Websockets Support** on the proxy host. ## Data & backups The `lifegame-data` volume (mounted at `/app/data`) is where the SQLite database and uploaded player tokens will live in later phases. It's empty now, but include it in the same backup routine as your other self-hosted data. ## What Phase 1 adds - The shared `game.js` rules engine (the pure reducer from the prototype) - SQLite data model: games, players, board/rule config, tokens - Rooms + shareable invite links / join codes - `NetworkTransport` on the client — the one-line swap that makes the game run across devices - Persistence & reconnection, since async means tabs close and servers restart