From 984ecc1da71790b5a7a96a1c7d3250b979013dcf Mon Sep 17 00:00:00 2001 From: jedarden Date: Sun, 29 Mar 2026 11:24:06 -0400 Subject: [PATCH] docs: Update deployment guide for K8s + B2 architecture - Replace Worker API references with K8s matchmaker/worker architecture - Update storage docs: R2 as warm cache, B2 as cold archive - Add PostgreSQL database configuration - Update health endpoint documentation for K8s probes - Add Traefik ingress and custom domain setup instructions - Remove obsolete D1 and Worker deployment sections Co-Authored-By: Claude Opus 4.6 --- .env.example | 28 ++++++------ DEPLOYMENT.md | 124 +++++++++++++++++++++----------------------------- 2 files changed, 65 insertions(+), 87 deletions(-) diff --git a/.env.example b/.env.example index 5a4ad91..d1958bd 100644 --- a/.env.example +++ b/.env.example @@ -2,26 +2,23 @@ # Copy this file to .env and fill in the values # =========================================== -# Worker API Configuration +# API Server Configuration # =========================================== -# The Cloudflare Worker API endpoint +# The API endpoint (Traefik ingress) ACB_API_ENDPOINT=https://api.aicodebattle.com -# Worker API key for authentication (required for workers and indexer) -ACB_API_KEY=your-worker-api-key-here - # =========================================== -# R2 Storage Configuration +# B2 Storage Configuration (S3-compatible) # =========================================== -# R2 endpoint URL (Cloudflare R2 S3-compatible endpoint) -ACB_R2_ENDPOINT=https://your-account-id.r2.cloudflarestorage.com +# B2 endpoint URL +ACB_B2_ENDPOINT=https://s3.us-east-005.backblazeb2.com -# R2 bucket name for replays and match data -ACB_R2_BUCKET=acb-data +# B2 bucket name for replays and match data +ACB_B2_BUCKET=acb-data -# R2 access credentials (from Cloudflare dashboard) -ACB_R2_ACCESS_KEY=your-r2-access-key-id -ACB_R2_SECRET_KEY=your-r2-secret-access-key +# B2 access credentials +ACB_B2_ACCESS_KEY=your-b2-key-id +ACB_B2_SECRET_KEY=your-b2-application-key # =========================================== # Bot Secrets (for local development) @@ -67,6 +64,7 @@ ACB_VERBOSE=false # =========================================== # Index Builder Configuration # =========================================== -# Optional: command to deploy generated files to Cloudflare Pages -# Example: wrangler pages deploy /app/data --project-name=aicodebattle +# Optional: command to deploy generated files +# For Cloudflare Pages: wrangler pages deploy /app/data --project-name=aicodebattle +# For B2: b2 sync /app/data b2://acb-data/data/ DEPLOY_COMMAND= diff --git a/DEPLOYMENT.md b/DEPLOYMENT.md index 127c5dd..67a60fb 100644 --- a/DEPLOYMENT.md +++ b/DEPLOYMENT.md @@ -8,24 +8,25 @@ The platform is split across two tiers: 1. **Cloudflare (free tier)** - Web-facing infrastructure - Pages: SPA shell + pre-computed JSON index files - - Worker: API endpoints for registration, job coordination - - D1: SQLite database for bots, matches, ratings - - R2: Replays, match metadata, maps, thumbnails + - R2: Replays, match metadata, maps, thumbnails (custom domain: r2.aicodebattle.com) -2. **Rackspace Spot** - Compute tier - - Match workers: Execute matches, upload replays to R2 +2. **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, deploys to Pages + - 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 - - Worker deployed - - D1 database created - - R2 bucket with custom domain configured -- Rackspace Spot account or equivalent container hosting -- Docker and docker-compose installed + - 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 @@ -35,9 +36,8 @@ The platform is split across two tiers: ``` 2. Edit `.env` and fill in your values: - - `ACB_API_ENDPOINT`: Your Cloudflare Worker URL - - `ACB_API_KEY`: Worker API key - - `ACB_R2_*`: R2 credentials from Cloudflare dashboard + - `ACB_DATABASE_URL`: PostgreSQL connection URL + - `ACB_R2_*`: B2/R2 credentials for replay storage - `BOT_SECRET_*`: Generate unique secrets for each bot ## Deploying Strategy Bots @@ -89,26 +89,29 @@ docker-compose -f docker-compose.workers.yml run indexer ## Cloudflare Configuration -### Worker API +### Pages Project -Deploy the worker: +Create the Pages project in Cloudflare dashboard: +1. Go to Workers & Pages > Create application > Pages > Upload assets +2. Project name: `aicodebattle` +3. Upload the `web/dist/` directory + +Or use wrangler CLI: ```bash -cd worker-api +npm install -g wrangler +wrangler login +cd web npm install -wrangler deploy +npm run build +wrangler pages deploy dist --project-name=aicodebattle ``` -### D1 Database +### Custom Domain for Pages -Create the database: -```bash -wrangler d1 create acb-db -``` - -Apply migrations (if any): -```bash -wrangler d1 execute acb-db --file=./schema.sql -``` +Configure custom domain in Cloudflare dashboard: +1. Go to your Pages project > Custom domains +2. Add domain: `aicodebattle.com` +3. DNS will be automatically configured ### R2 Bucket @@ -118,77 +121,54 @@ wrangler r2 bucket create acb-data ``` Configure custom domain in Cloudflare dashboard: -- Domain: `data.aicodebattle.com` -- Bucket: `acb-data` +1. Go to R2 > acb-data > Settings > Custom Domains +2. Add domain: `r2.aicodebattle.com` -### Pages +### DNS Configuration -Deploy the web SPA: -```bash -cd web -npm install -npm run build -wrangler pages deploy dist --project-name=aicodebattle -``` +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 Worker API provides two health endpoints for monitoring: +The API server provides health endpoints for Kubernetes probes: - **Liveness**: `GET /health` or `GET /api/health` - - Returns 200 if the worker process is running - - Use for Kubernetes liveness probes + - Returns 200 if the process is running - **Readiness**: `GET /ready` or `GET /api/ready` - - Returns 200 if database is connected and ready + - Returns 200 if database is connected - Returns 503 if database is unavailable - - Use for Kubernetes readiness probes -Example responses: +### Kubernetes Monitoring -```json -// GET /health -{ - "success": true, - "data": { - "status": "healthy", - "timestamp": "2024-01-15T10:30:00.000Z" - } -} - -// GET /ready (when healthy) -{ - "success": true, - "data": { - "status": "ready", - "database": "connected", - "timestamp": "2024-01-15T10:30:00.000Z" - } -} -``` +- Use `kubectl --server=http://kubectl-apexalgo-iad:8001` for 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 -- Worker Logs: `wrangler tail` -- Container Logs: `docker-compose logs -f` +- Pages deployments: Workers & Pages > aicodebattle ## Troubleshooting ### Worker can't connect to API -Check that `ACB_API_ENDPOINT` is correct and accessible from the worker container. +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 Worker API. +Verify `BOT_SECRET_*` values match what's registered in the database. -### R2 upload failures +### B2/R2 upload failures -Check R2 credentials and bucket permissions. +Check B2/R2 credentials and bucket permissions. ### Index builder not deploying -Ensure `DEPLOY_COMMAND` is set correctly and Cloudflare API token has Pages deploy permissions. +Ensure `DEPLOY_COMMAND` is set correctly and credentials have upload permissions.