Quick Start
Three development modes depending on what you're testing.
Prerequisitesβ
- Node.js β₯22.12
git clonethe repo andcd SommelierArena
Mode A β Fast daily dev (recommended)β
Best for feature work. No Docker needed.
# Terminal 1 β PartyKit backend (port 1999)
npx partykit dev
npx partykit dev runs a local in-memory simulator β it emulates Cloudflare Durable Objects entirely on your machine with no internet connection required. Note: Cloudflare KV (HOSTS_KV) is disabled in all environments (binding removed β see Data Persistence); session history comes from browser localStorage only.
Whenever you modify files under back/ (game.ts, utils.ts, constants.ts, etc.), you must redeploy to Cloudflare for the changes to take effect in production:
npx partykit deploy # from repo root
# or
cd back && npm run deploy
The proxy-worker does not need redeployment for backend-only changes.
# Terminal 2 β Astro frontend (port 4321)
cd front
cp .env.example .env.local # PUBLIC_PARTYKIT_HOST=localhost:1999
npm run dev
Open http://localhost:4321/host (host), http://localhost:4321/play (participant), and http://localhost:4321/admin (admin dashboard).
Mode B β Full integration (Docker)β
Best for E2E tests and nginx/proxy validation.
docker-compose up --build
| Service | URL |
|---|---|
| Frontend (nginx) | http://localhost:4321 |
| PartyKit backend | http://localhost:1999 |
| Wine Answers Worker | http://localhost:1998 |
| Docs (Docusaurus) | http://localhost:3002 |
Why nginx?β
In Mode B, the front container runs nginx instead of the Astro dev server. nginx is necessary because:
- Astro builds to static files β
npm run buildproduces plain HTML/JS/CSS; there's no Node.js server at request time, so something must serve them. - SPA routing β nginx's
try_files $uri $uri/index.html /index.htmlensures/hostand/playreturnindex.htmlwithout a 404.
absolute_redirect off in front/nginx.conf ensures nginx uses relative Location headers, which is safer for SPA routing in various proxy environments.
WebSocket traffic is direct β nginx does not proxy WebSocket connections. The browser connects directly to
ws://localhost:1999/parties/main/{code}(thebackcontainer is exposed on host port 1999). This keeps the nginx config simple with no/parties/location block.
For daily development, you don't need nginx at all β Mode A uses Astro's built-in dev server on port 4321, which handles routing natively via PUBLIC_PARTYKIT_HOST.
Docker cheat sheetβ
# Start the full stack
docker-compose up --build -d
# Stop the full stack
docker-compose down
# Rebuild a single service
docker-compose up --build -d front
# View logs
docker-compose logs -f
β οΈ Important: Use
docker-compose downto stop the running stack. If you started the stack with additional flags or in a different context, ensure you stop the correct compose project instance.
Mode C β Docs onlyβ
cd docs-site
npm run start:local
# β http://localhost:3002
Docs site β local search & previewβ
This project uses a local, file-based search plugin for Docusaurus to provide a search box in the docs navbar.
Quick start (dev):
-
Install dependencies:
cd docs-site
npm ci -
Start the dev server (live reload):
npm run start:local -
Open http://localhost:3002 and use the search box in the navbar.
Preview built site (parity with production)
This repository standardizes on building the docs for deployment under /docs (Cloudflare Pages). To preview the site exactly as production will serve it:
# Build with DOCS_BASE_URL=/docs
cd docs-site
npm run build:local
# Serve the built site mounted at /docs
npm run serve:docs
# β http://localhost:3002/docs
If you prefer to preview the site at root (/), build with DOCS_BASE_URL=/ and use npm run serve to open http://localhost:3002/.
Notes
- The plugin dependency (
@cmfcmf/docusaurus-search-local) is declared inpackage.jsonand will be installed bynpm ci. - If you build inside Docker or CI,
npm ciin the Dockerfile ensures the plugin is available. - See the Configuration & Environments page for env var details and storage layer breakdown.
Certificates / Playwright trustβ
If your network performs TLS interception (corporate proxy like Zscaler), Playwright's browser downloads may fail with TLS errors. Convert your organization's root certificate to PEM and use it for the single Playwright install command.
- Convert DER (
.cer/.crt) to PEM if needed:
openssl x509 -in "/path/to/org-root-ca.cer" -inform DER -out "/path/to/org-root-ca.pem" -outform PEM
- Run the Playwright installer from the e2e directory while trusting the PEM file (one-off):
cd e2e
NODE_EXTRA_CA_CERTS="/path/to/org-root-ca.pem" npx playwright install --with-deps
Notes:
- Use a full filesystem path for
NODE_EXTRA_CA_CERTS(do not check the PEM into source control). - If you are behind an HTTP proxy, prefix the command with
HTTPS_PROXY="http://proxy:port". - Avoid
NODE_TLS_REJECT_UNAUTHORIZED=0in CI or shared environments β it disables TLS verification globally.
Run testsβ
# Frontend unit tests (Vitest + RTL)
cd front && npm test
# E2E tests (requires Mode B Docker stack running)
cd e2e && npm test -- --project=chromium
Environment variablesβ
| Variable | Where | Value |
|---|---|---|
PUBLIC_PARTYKIT_HOST | front/.env.local | localhost:1999 (local) |
PUBLIC_PARTYKIT_HOST | Cloudflare Pages dashboard | sommelier-arena.USERNAME.partykit.dev (prod) |
PUBLIC_WINE_ANSWERS_URL | front/.env.local | http://localhost:1998 (local) |
PUBLIC_WINE_ANSWERS_URL | Cloudflare Pages dashboard | https://<wine-answers-worker>.workers.dev (prod) |
See front/.env.example for a template.
Note: Sessions persist in your browser's localStorage. Use the π button on the Host Dashboard to clean up old sessions.