Add automated script for creating R2 bucket and configuring custom domain r2.aicodebattle.com for replay storage. - Create scripts/setup-r2.sh: - Creates acb-data R2 bucket if it doesn't exist - Configures custom domain via Cloudflare API - Includes verification and usage instructions - Update DEPLOYMENT.md to reference the new script Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.9 KiB
AI Code Battle - Deployment Guide
This document describes how to deploy AI Code Battle to production.
Architecture Overview
The platform is split across two tiers:
-
Cloudflare (free tier) - Web-facing infrastructure
- Pages: SPA shell + pre-computed JSON index files
- R2: Replays, match metadata, maps, thumbnails (custom domain: r2.aicodebattle.com)
-
Kubernetes (apexalgo-iad) - Compute tier
- Matchmaker: Pairs bots, creates jobs in PostgreSQL
- Match workers: Execute matches, upload replays to B2
- Bot containers: Run strategy bot HTTP servers
- Index builder: Generates JSON indexes, uploads to B2/Pages
- PostgreSQL: Bots, matches, ratings, job queue
- Traefik: Ingress for api.aicodebattle.com
Prerequisites
- Cloudflare account with:
- Pages project created (aicodebattle)
- R2 bucket with custom domain configured (r2.aicodebattle.com)
- Kubernetes cluster with:
- PostgreSQL database
- Traefik ingress
- Docker and docker-compose installed (for local development)
Environment Setup
-
Copy the example environment file:
cp .env.example .env -
Edit
.envand fill in your values:ACB_DATABASE_URL: PostgreSQL connection URLACB_R2_*: B2/R2 credentials for replay storageBOT_SECRET_*: Generate unique secrets for each bot
Deploying Strategy Bots
The strategy bots run as HTTP servers that the match workers call during games.
# Build and start all 6 strategy bots
docker-compose -f docker-compose.bots.yml up -d
# Check status
docker-compose -f docker-compose.bots.yml ps
# View logs
docker-compose -f docker-compose.bots.yml logs -f
Bot endpoints will be available at:
- RandomBot: http://localhost:8081/turn
- GathererBot: http://localhost:8082/turn
- RusherBot: http://localhost:8083/turn
- GuardianBot: http://localhost:8084/turn
- SwarmBot: http://localhost:8085/turn
- HunterBot: http://localhost:8086/turn
Deploying Match Workers
Match workers poll the Worker API for pending jobs and execute matches.
# Build and start match workers
docker-compose -f docker-compose.workers.yml up -d
# Scale workers based on load
docker-compose -f docker-compose.workers.yml up -d --scale worker=3
Running the Index Builder
The index builder generates static JSON files for the web platform.
# Run once to generate index files
docker-compose -f docker-compose.workers.yml run indexer
# For automatic deployment, set DEPLOY_COMMAND in .env:
# DEPLOY_COMMAND=wrangler pages deploy /app/data --project-name=aicodebattle
Cloudflare Configuration
Pages Project
Create the Pages project in Cloudflare dashboard:
- Go to Workers & Pages > Create application > Pages > Upload assets
- Project name:
aicodebattle - Upload the
web/dist/directory
Or use wrangler CLI:
npm install -g wrangler
wrangler login
cd web
npm install
npm run build
wrangler pages deploy dist --project-name=aicodebattle
Custom Domain for Pages
Configure custom domain in Cloudflare dashboard:
- Go to your Pages project > Custom domains
- Add domain:
aicodebattle.com - DNS will be automatically configured
R2 Bucket
Create the bucket and configure custom domain:
# Automated setup (bucket + custom domain via API)
./scripts/setup-r2.sh
# Or manual setup:
# 1. Create bucket
wrangler r2 bucket create acb-data
# 2. Configure custom domain in Cloudflare dashboard:
# - Go to R2 > acb-data > Settings > Custom Domains
# - Add domain: r2.aicodebattle.com
DNS Configuration
In Cloudflare DNS settings:
aicodebattle.com→ CNAME to Pages (auto-configured when adding custom domain)api.aicodebattle.com→ A record pointing to Traefik LoadBalancer IP (proxied)r2.aicodebattle.com→ CNAME to R2 (auto-configured when adding custom domain)
Monitoring
Health Endpoints
The API server provides health endpoints for Kubernetes probes:
-
Liveness:
GET /healthorGET /api/health- Returns 200 if the process is running
-
Readiness:
GET /readyorGET /api/ready- Returns 200 if database is connected
- Returns 503 if database is unavailable
Kubernetes Monitoring
- Use
kubectl --server=http://kubectl-apexalgo-iad:8001for read-only cluster access - Check pod status:
kubectl get pods -n ai-code-battle - View logs:
kubectl logs -n ai-code-battle deployment/acb-matchmaker
Cloudflare Monitoring
- Cloudflare Analytics: Available in Cloudflare dashboard
- Pages deployments: Workers & Pages > aicodebattle
Troubleshooting
Worker can't connect to API
Check that the API service is running and accessible via Traefik ingress at api.aicodebattle.com.
Bot authentication failures
Verify BOT_SECRET_* values match what's registered in the database.
B2/R2 upload failures
Check B2/R2 credentials and bucket permissions.
Index builder not deploying
Ensure DEPLOY_COMMAND is set correctly and credentials have upload permissions.