docs: replace R2 with B2 throughout deployment docs

Cloudflare R2 was never the intended storage layer — plan.md correctly
specifies Backblaze B2 via Cloudflare Bandwidth Alliance. Remove the
Cloudflare R2 Setup section from the phase6 checklist, replace all
r2.aicodebattle.com URLs with b2.aicodebattle.com, fix the data flow
diagram to show K8s cluster as write-only compute (battles + replay
building) with no inbound user traffic, and update spa-route-test-results
to reference /b2/ paths consistently.
This commit is contained in:
jedarden 2026-06-07 08:50:34 -04:00
parent 00aece3f62
commit faf8770dee
2 changed files with 110 additions and 119 deletions

View file

@ -11,7 +11,7 @@ This document outlines the remaining steps to complete Phase 6. All code is writ
### ✅ Container Images
- [x] `acb-matchmaker` - Match scheduling, health checks, reaper
- [x] `acb-worker` - Match execution, B2 upload
- [x] `acb-index-builder` - PostgreSQL → JSON → Pages deploy, R2 management
- [x] `acb-index-builder` - PostgreSQL → JSON → Pages deploy
- [x] `acb-evolver` - LLM evolution pipeline
- [x] `acb-strategy-random` - Python RandomBot
- [x] `acb-strategy-gatherer` - Go GathererBot
@ -46,7 +46,7 @@ All K8s manifests are in the `ardenone-cluster` repo at:
### ✅ Deployment Scripts
All scripts in `scripts/` directory are ready:
- [x] `cloudflare-setup.sh` - Full Cloudflare setup
- [x] `setup-r2.sh` - R2 bucket + custom domain
- [x] `setup-b2.sh` - B2 bucket configuration (obsolete — B2 credentials already in SealedSecrets)
- [x] `deploy-pages.sh` - Deploy SPA to Pages
- [x] `configure-dns.sh` - DNS configuration
- [x] `verify-deployment.sh` - End-to-end verification
@ -85,25 +85,19 @@ All scripts in `scripts/` directory are ready:
- Add domain: `aicodebattle.com`
- DNS CNAME will be auto-configured
### ⏳ Cloudflare R2 Setup
### ⏳ Backblaze B2 Custom Domain
**Automated via script:**
```bash
export CLOUDFLARE_API_TOKEN=your_token
export CLOUDFLARE_ACCOUNT_ID=your_account_id # optional, auto-detected
./scripts/setup-r2.sh
```
B2 credentials are already provisioned (SealedSecret in cluster). The remaining step is to
expose the bucket under a `b2.aicodebattle.com` subdomain so the SPA can fetch replays
via Cloudflare's Bandwidth Alliance (zero egress fees).
**Or manual steps:**
1. Create R2 bucket:
```bash
wrangler r2 bucket create acb-data
```
**Manual steps:**
1. In Backblaze console, enable public access on the `acb-data` bucket.
2. Note the native B2 endpoint: `{bucket}.s3.{region}.backblazeb2.com`
3. Add a Cloudflare DNS CNAME (see DNS section below) — Cloudflare proxies the request,
activating the Bandwidth Alliance and serving files via CDN.
2. Add custom domain:
- Go to: R2 > acb-data > Settings > Custom Domains
- Add domain: `r2.aicodebattle.com`
- DNS CNAME will be auto-configured
No script required — no Cloudflare account credentials needed for this step (DNS-only change).
### ⏳ DNS Configuration
@ -121,13 +115,13 @@ export TRAEFIK_IP=$(kubectl --server=http://kubectl-apexalgo-iad:8001 get svc -n
- Target: `aicodebattle.pages.dev`
- Proxy: On (orange cloud)
2. R2 subdomain:
2. B2 subdomain (Bandwidth Alliance):
- Type: CNAME
- Name: `r2`
- Target: `acb-data.r2.cloudflarestorage.com`
- Proxy: Off (gray cloud) - DNS only
- Name: `b2`
- Target: `acb-data.s3.<region>.backblazeb2.com` ← replace `<region>` with actual B2 region
- Proxy: On (orange cloud) — required to activate Cloudflare Bandwidth Alliance (zero egress)
3. API subdomain:
3. API subdomain (deferred — not needed for v1 static-first launch):
- Type: A
- Name: `api`
- Target: `<Traefik LoadBalancer IP>`
@ -153,11 +147,11 @@ Or manually check:
# SPA should be accessible
curl -I https://aicodebattle.com
# R2 should be accessible
curl -I https://r2.aicodebattle.com
# B2 CDN should be accessible (a known replay file)
curl -I https://b2.aicodebattle.com/replays/latest.json.gz
# API health (once K8s is running)
curl https://api.aicodebattle.com/health
# API health (deferred — not required for v1)
# curl https://api.aicodebattle.com/health
```
---
@ -168,85 +162,83 @@ curl https://api.aicodebattle.com/health
|---------|-----|
| SPA (Pages) | `https://aicodebattle.com` |
| SPA (Pages default) | `https://aicodebattle.pages.dev` |
| Replays (R2) | `https://r2.aicodebattle.com/replays/{match_id}.json.gz` |
| Match metadata (R2) | `https://r2.aicodebattle.com/matches/{match_id}.json` |
| Evolution feed (R2) | `https://r2.aicodebattle.com/evolution/live.json` |
| API (K8s) | `https://api.aicodebattle.com/health` |
| Replays (B2 via CDN) | `https://b2.aicodebattle.com/replays/{match_id}.json.gz` |
| Match metadata (B2 via CDN) | `https://b2.aicodebattle.com/matches/{match_id}.json` |
| Evolution feed (B2 via CDN) | `https://b2.aicodebattle.com/evolution/live.json` |
| API (K8s, deferred) | `https://api.aicodebattle.com/health` |
---
## Data Flow
```
┌─────────────────────────────────────────────────────────────────┐
│ Public Internet │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────┐ ┌─────────────────────────────────┐ │
│ │ Cloudflare Pages │ │ Cloudflare R2 │ │
│ │ aicodebattle.com │ │ r2.aicodebattle.com │ │
│ │ │ │ │ │
│ │ SPA shell (HTML/ │ │ replays/*.json.gz │ │
│ │ JS/CSS) │ │ matches/*.json │ │
│ │ data/*.json │ │ evolution/live.json │ │
│ │ │ │ │ │
│ └─────────────────────┘ └─────────────────────────────────┘ │
│ ▲ ▲ │
└───────────┼────────────────────────────┼────────────────────────┘
│ │
┌───────────┼────────────────────────────┼────────────────────────┐
│ │ apexalgo-iad cluster │ │
│ │ │ │
│ ┌────────▼─────────────────────────────┼────────────────────┐ │
│ │ Index Builder Deployment │ │ │
│ │ - Reads PostgreSQL │ │ │
│ │ - Generates JSON indexes │ │ │
│ │ - Deploys to Pages (wrangler) │ │ │
│ │ - Promotes replays to R2 │ │ │
│ │ - Prunes R2 warm cache │ │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Match Workers (Deployment) │ │
│ │ - Execute matches │ │
│ │ - Upload replays to B2 │ │
│ │ - Write results to PostgreSQL │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Matchmaker Deployment │ │
│ │ - Creates match jobs │ │
│ │ - Enqueues to Valkey │ │
│ │ - Health checks bots │ │
│ │ - Reaps stale jobs │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Evolver Deployment │ │
│ │ - LLM evolution pipeline │ │
│ │ - Writes evolution/live.json to R2 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Strategy Bot Deployments (x6) │ │
│ │ - HTTP servers on cluster-internal Services │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ PostgreSQL (cnpg-apexalgo) │ │
│ │ - Bots, matches, jobs, ratings, etc. │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Valkey StatefulSet │ │
│ │ - Job queue (acb:jobs:pending) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Backblaze B2 (cold archive) │ │
│ │ - ALL replays, permanently │ │
│ └─────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Public Internet │
│ (No K8s services exposed here — cluster is write-only compute) │
├──────────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────┐ ┌────────────────────────────────────┐ │
│ │ Cloudflare Pages │ │ Backblaze B2 (via Cloudflare CDN) │ │
│ │ aicodebattle.com │ │ b2.aicodebattle.com │ │
│ │ │ │ │ │
│ │ SPA shell (HTML/ │ │ replays/*.json.gz │ │
│ │ JS/CSS) │ │ matches/*.json │ │
│ │ data/*.json │ │ evolution/live.json │ │
│ │ │ │ (Bandwidth Alliance = free egress) │ │
│ └──────────────────────┘ └────────────────────────────────────┘ │
│ ▲ ▲ │
└───────────┼───────────────────────────────┼──────────────────────────┘
writes (wrangler) writes (S3-compatible API)
│ │
┌───────────┼───────────────────────────────┼──────────────────────────┐
│ │ apexalgo-iad cluster │ │
│ │ (compute only — no │ │
│ │ inbound user traffic) │ │
│ │ │ │
│ ┌────────▼───────────────────────────────┼────────────────────────┐ │
│ │ Index Builder Deployment │ │ │
│ │ - Reads PostgreSQL │ │ │
│ │ - Generates JSON indexes │ │ │
│ │ - Deploys data/*.json to Pages (wrangler pages deploy) │ │
│ └────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Match Workers (Deployment) │ │
│ │ - Execute matches (battles happen here) │ │
│ │ - Build replay JSON │ │
│ │ - Upload replays to B2 │ │
│ │ - Write results to PostgreSQL │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Matchmaker Deployment │ │
│ │ - Creates match jobs │ │
│ │ - Enqueues to Valkey │ │
│ │ - Health checks bots │ │
│ │ - Reaps stale jobs │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Evolver Deployment │ │
│ │ - LLM evolution pipeline │ │
│ │ - Writes evolution/live.json to B2 │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Strategy Bot Deployments (x6) │ │
│ │ - HTTP servers on cluster-internal Services only │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ PostgreSQL (cnpg-apexalgo) │ │
│ │ - Bots, matches, jobs, ratings, etc. │ │
│ └──────────────────────────────────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────┐ │
│ │ Valkey StatefulSet │ │
│ │ - Job queue (acb:jobs:pending) │ │
│ └──────────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────────┘
```
---
@ -257,17 +249,16 @@ Once Cloudflare resources are created:
1. **Update environment variables in index builder:**
- `CLOUDFLARE_API_TOKEN` - For Pages deployment
- `R2_ACCESS_KEY_ID`, `R2_SECRET_ACCESS_KEY`, `R2_BUCKET`, `R2_ENDPOINT` - For R2 operations
- `B2_KEY_ID`, `B2_APPLICATION_KEY`, `B2_BUCKET`, `B2_ENDPOINT` - For B2 operations
- `B2_KEY_ID`, `B2_APPLICATION_KEY`, `B2_BUCKET`, `B2_ENDPOINT` - For B2 operations (workers and evolver)
2. **Deploy to Kubernetes:**
- K8s manifests are already in `ardenone-cluster` repo
- ArgoCD will sync them automatically
3. **Verify data flow:**
- Index builder should start deploying to Pages
- Match workers should upload replays to B2
- R2 warm cache should populate with recent replays
- Index builder should start deploying JSON indexes to Pages
- Match workers should upload replay files to B2
- Replays should be accessible at `b2.aicodebattle.com` via Cloudflare CDN
4. **Monitor:**
- Check ArgoCD for sync status
@ -285,8 +276,8 @@ Phase 6 is complete when:
- [x] CI/CD pipeline working
- [x] Monitoring and alerting configured
- [ ] Cloudflare Pages project created and deployed
- [ ] Cloudflare R2 bucket created with custom domain
- [ ] DNS configured (aicodebattle.com, r2.aicodebattle.com, api.aicodebattle.com)
- [ ] B2 bucket public access enabled and `b2.aicodebattle.com` CNAME added (Bandwidth Alliance)
- [ ] DNS configured (aicodebattle.com, b2.aicodebattle.com)
- [ ] Platform publicly accessible
The final 3 items require Cloudflare account access and must be completed by someone with admin access to the Cloudflare account.
The Pages and DNS items require Cloudflare account access. The B2 item requires Backblaze console access. The `api.aicodebattle.com` DNS entry is deferred — the Go API is not required for v1.

View file

@ -14,7 +14,7 @@
| **Failed** | 0 |
| **Total** | 43 |
**Result:** All SPA routes return valid HTML. The /r2/ data paths return 404 (data not yet deployed to R2/Pages Function).
**Result:** All SPA routes return valid HTML. The /b2/ data paths return 404 (data not yet deployed — B2 bucket not yet publicly accessible and index builder not yet running).
## Static Routes (All Passed)
@ -67,21 +67,21 @@
| `/blog/:slug` | Blog post | 200 OK |
| `/watch/playlists/:slug` | Playlist detail | 200 OK |
Note: Parameterized routes tested with placeholder IDs. Routes return valid SPA shell; actual data loading depends on /r2/ data path.
Note: Parameterized routes tested with placeholder IDs. Routes return valid SPA shell; actual data loading depends on `/b2/` data paths served from Backblaze B2 via Cloudflare CDN.
## Data Paths (/r2/) - 404 Expected
## Data Paths (/b2/) - 404 Expected
| Path | Description | Status |
|------|-------------|--------|
| `/r2/` | R2 data root | 404 Not Found |
| `/r2/data/matches/index.json` | Matches index | 404 Not Found |
| `/r2/data/leaderboard.json` | Leaderboard data | 404 Not Found |
| `/r2/data/seasons/index.json` | Seasons index | 404 Not Found |
| `/r2/data/series/index.json` | Series index | 404 Not Found |
| `/r2/data/blog/index.json` | Blog index | 404 Not Found |
| `/r2/data/playlists/index.json` | Playlists index | 404 Not Found |
| `/b2/` | B2 data root | 404 Not Found |
| `/b2/data/matches/index.json` | Matches index | 404 Not Found |
| `/b2/data/leaderboard.json` | Leaderboard data | 404 Not Found |
| `/b2/data/seasons/index.json` | Seasons index | 404 Not Found |
| `/b2/data/series/index.json` | Series index | 404 Not Found |
| `/b2/data/blog/index.json` | Blog index | 404 Not Found |
| `/b2/data/playlists/index.json` | Playlists index | 404 Not Found |
**Note:** These 404s are expected - the data has not been uploaded to R2 or the Pages Function has not been configured yet. This is a data availability issue, not a routing issue. See related bead `bf-cmh1` for end-to-end replay viewer testing.
**Note:** These 404s are expected — the B2 bucket is not yet publicly accessible and the index builder is not yet running. Data paths are served from Backblaze B2 (not Cloudflare R2). This is a data availability issue, not a routing issue. See related bead `bf-cmh1` for end-to-end replay viewer testing.
## Test Script