Skip to main content

Overview

Hyperscape uses Railway for production server deployment with automated GitHub Actions integration. The server handles both the game API and serves the frontend application.

Production Architecture

Automated Deployment

GitHub Actions Workflow

The repository includes automated Railway deployment:
Deployment triggers only when relevant files change to avoid unnecessary builds.

Setup GitHub Actions

1

Generate Railway API token

  1. Go to Railway dashboard → Account Settings → Tokens
  2. Create new token with deployment permissions
  3. Copy the token
2

Add GitHub secret

  1. Go to GitHub repository → Settings → Secrets and variables → Actions
  2. Add new repository secret: RAILWAY_TOKEN
  3. Paste the Railway API token
3

Configure project IDs

Update .github/workflows/deploy-railway.yml with your Railway IDs:
Find these in Railway dashboard → Project → Settings → General

Build Configuration

Nixpacks

Railway uses Nixpacks for building. Configuration in nixpacks.toml:

Railway Configuration

The railway.server.json file configures Railway deployment:

Environment Variables

Configure these in Railway dashboard → Variables:

Required

Optional

Frontend Integration

The Railway deployment includes the frontend client:

Build Process

  1. Build shared package - Core engine with ECS, Three.js, PhysX
  2. Build client package - React frontend with Vite
  3. Build server package - Fastify server with WebSocket support
  4. Copy client to server - packages/client/dist/packages/server/public/

Serving Strategy

The server serves both the API and the frontend:
Routes:
  • / - Frontend application (index.html)
  • /api/* - REST API endpoints
  • /ws - WebSocket connection
  • /manifests/* - Game data manifests (fetched from CDN)
  • /assets/* - Client assets (JS, CSS from built frontend)
  • /status - Health check endpoint

Manifest Fetching

On server startup, manifests are fetched from the CDN:
Behavior:
  • Fetches all manifests from CDN at startup
  • Compares with existing local files
  • Only writes if content changed (avoids unnecessary disk I/O)
  • Falls back to local manifests if CDN fetch fails
  • Logs fetch results: “X fetched, Y updated, Z failed”
Benefits:
  • Update game content by deploying new manifests to CDN
  • No server redeployment needed for content changes
  • Server always has latest game data
  • Reduces deployment size

Deployment Verification

After deployment, verify the server is running:
Expected responses:
  • /status - {"status": "ok", ...}
  • / - HTML content (frontend)
  • /manifests/items.json - JSON manifest data
  • /ws - WebSocket upgrade successful

Troubleshooting

Build Failures

Symptom: Railway build fails during build phase Common Causes:
  • Lockfile out of sync: bun install && git add bun.lock
  • Missing environment variables: Check Railway dashboard
  • Build timeout: Optimize build or upgrade Railway plan
Check logs:
  • Railway dashboard → Deployments → View logs
  • Look for specific error messages in build phase

Frontend Not Serving

Symptom: Server returns 503 “Frontend not available” Cause: Client build not copied to server’s public/ directory Solution: Verify nixpacks.toml includes:

Manifest Fetch Failures

Symptom: Server logs show “Failed to fetch manifests from CDN” Solutions:
  1. Verify PUBLIC_CDN_URL is set correctly in Railway variables
  2. Test CDN accessibility: curl $PUBLIC_CDN_URL/manifests/items.json
  3. Check Railway logs for specific fetch errors
  4. Ensure manifests are deployed to CDN
Fallback: Server will use local manifests if CDN fetch fails.

CORS Errors

Symptom: Browser console shows CORS errors Cause: Frontend domain not in server’s CORS allowlist Solution: The server automatically allows:
  • https://hyperscape.club
  • https://www.hyperscape.club
  • https://hyperscape.pages.dev
  • https://*.hyperscape.pages.dev
  • https://*.up.railway.app
For custom domains, set PUBLIC_APP_URL environment variable in Railway.

Manual Deployment

If not using GitHub Actions, deploy manually:

Monitoring

Railway Dashboard

Monitor deployment health:
  • Deployments → View build logs
  • Metrics → CPU, memory, network usage
  • Logs → Real-time server logs

Health Checks

Railway automatically monitors /status endpoint:
  • Timeout: 300 seconds
  • Restart policy: ON_FAILURE
  • Max retries: 3

Scaling

Railway supports horizontal scaling:
Horizontal scaling requires session affinity for WebSocket connections. Configure Railway load balancer accordingly.