Overview
Hyperscape uses Railway for production server deployment with automated GitHub Actions integration. The deployment uses Nixpacks for building and includes automatic manifest fetching from CDN.Architecture
The production deployment uses a split architecture:- Frontend: Cloudflare Pages (
hyperscape.club) - Server/API: Railway (
hyperscape-production.up.railway.app) - Assets/CDN: Cloudflare R2 (
assets.hyperscape.club) - Database: Railway PostgreSQL
Prerequisites
- Railway account (railway.app)
- GitHub repository connected to Railway
- Cloudflare R2 bucket for assets (or alternative CDN)
- Privy account for authentication
Initial Setup
Create Railway project
- Sign up at railway.app
- Click “New Project”
- Select “Deploy from GitHub repo”
- Choose your Hyperscape repository
- Select the
mainbranch
Add PostgreSQL database
- In your Railway project, click “New”
- Select “Database” → “Add PostgreSQL”
- Railway automatically sets
DATABASE_URLenvironment variable - Database migrations run automatically on server startup
Build Configuration
Nixpacks Configuration
Railway usesnixpacks.toml in the repository root:
- Only builds
sharedandserverpackages (client is on Cloudflare Pages) - Creates manifests directory for CDN-fetched manifests
- Skips asset download (
SKIP_ASSETS=true) - assets served from CDN - Forces fresh Turbo builds to avoid cache issues
Service Configuration
railway.server.json defines the service:
Railway Ignore
.railwayignore excludes unnecessary files from upload:
Automated Deployment
GitHub Actions Workflow
The repository includes.github/workflows/deploy-railway.yml for automated deployments:
- Automatic on push to
mainwhen relevant files change - Manual via GitHub Actions UI (
workflow_dispatch)
- Triggers Railway deployment via GraphQL API
- Waits for deployment to start
- Polls deployment status (5 attempts, 30s intervals)
- Reports success/failure
Setup GitHub Actions
Get Railway token
- Go to railway.app/account/tokens
- Create a new token
- Copy the token value
Add GitHub secret
- Go to your GitHub repository → Settings → Secrets and variables → Actions
- Click “New repository secret”
- Name:
RAILWAY_TOKEN - Value: Your Railway token
- Click “Add secret”
Manifest Loading
The server fetches game manifests from CDN at startup instead of requiring local assets:- No Git LFS required in production
- Faster deployments (no asset cloning)
- Manifests cached locally for 5 minutes
- Automatic updates when CDN manifests change
- Production/CI: Always fetches from CDN
- Development: Skips fetch if local manifests exist
- Caching: Manifests cached in
world/assets/manifests/
CORS Configuration
The server automatically allows requests from:CLIENT_URLPUBLIC_APP_URLELIZAOS_URL/ELIZAOS_API_URL
Troubleshooting
Build Failures
“lockfile frozen” error:- Nixpacks installs required system dependencies (Cairo, Pango, etc.)
- Check Railway build logs for missing packages
- Add to
aptPkgsinnixpacks.tomlif needed
Runtime Issues
Manifests not loading:- Verify
PUBLIC_CDN_URLis set correctly - Check CDN is serving manifests at
/manifests/*.json - Review Railway logs for fetch errors
- Ensure CORS headers allow Railway domain
- Railway serves API only - frontend is on Cloudflare Pages
- Verify CORS origins include your Cloudflare Pages domain
- Check
CLIENT_URLenvironment variable
- Railway PostgreSQL sets
DATABASE_URLautomatically - Verify database service is running in Railway dashboard
- Check connection string format:
postgresql://user:pass@host:port/db
Deployment Status
Check deployment status in Railway:- Go to Railway dashboard → Your project
- Click on the service
- View “Deployments” tab
- Check logs for errors
Monitoring
Health Checks
Railway uses the/status endpoint for health checks:
- Path:
/status - Timeout: 300 seconds
- Restart policy:
ON_FAILUREwith 3 max retries
Logs
View logs in Railway dashboard or via CLI:Scaling
Railway supports horizontal scaling:- Go to Railway dashboard → Service → Settings
- Adjust “Replicas” count
- Railway handles load balancing automatically
Hyperscape is designed for vertical scaling (single instance). Horizontal scaling requires session affinity (sticky sessions) for WebSocket connections.
Cost Optimization
Resource Limits
Set resource limits in Railway dashboard:- Memory: 2GB recommended minimum
- CPU: 1 vCPU sufficient for 50-100 concurrent players
- Disk: 1GB for database and logs
Deployment Frequency
The GitHub Actions workflow only triggers on relevant file changes:Alternative: Docker Deployment
If you prefer Docker over Nixpacks, useDockerfile.server:
- Railway dashboard → Service → Settings
- Change “Builder” to “Dockerfile”
- Set “Dockerfile Path” to
Dockerfile.server - Redeploy