Production Deployment
Complete guide to deploying the AltSportsLeagues.ai platform to production, including domain mapping, SSL configuration, and verification steps.
ποΈ Deployment Architecture
π Phase 1: Backend Deployment
Test Locally First (CRITICAL)
Always test in local Docker before deploying to Cloud Run!
cd apps/backend
./deploy-local-docker.shWait for deployment (~30 seconds), then test:
# Health check
curl http://localhost:8090/health
# API docs
open http://localhost:8090/docs
# Test endpoints
curl http://localhost:8090/v1/leagues
# View logs
docker compose logs -fβ Expected: All endpoints return 200 OK, no errors in logs
Stop when done:
docker compose downDeploy to Cloud Run
Navigate to project root and run deployment script:
cd /Users/kbselander/Developer/Notebook/mcp-servers/servers/mcp-server-altsportsleagues.ai/2.1-cloud-run-docker-mcp
./deploy-all.shSelect: Option 2 (Backend only)
Wait: 4-8 minutes for build and deployment
Monitor: Watch the terminal for progress:
Building Docker image...
Pushing to Google Container Registry...
Deploying to Cloud Run...
β
Deployment complete!The script saves the URL to .backend-url:
cat .backend-url
# Example: https://altsportsleagues-backend-xxx-uc.a.run.appMap Custom Domain
In Google Cloud Console:
- Go to Cloud Run Console (opens in a new tab)
- Click service:
altsportsleagues-backend - Click "Manage Custom Domains" tab
- Click "Add Mapping"
- Enter domain:
api.altsportsleagues.ai - Select region:
us-central1 - Click Continue
- Note the CNAME target:
ghs.googlehosted.com - Status shows: "Pending Verification"
In Cloudflare:
- Go to Cloudflare Dashboard (opens in a new tab)
- Select domain:
altsportsleagues.ai - Go to DNS β Records
- Click Add Record
- Configure:
- Type: CNAME
- Name:
api - Target:
ghs.googlehosted.com - Proxy status: βοΈ Proxied (orange cloud)
- TTL: Auto
- Click Save
Wait: 5-30 minutes for verification and SSL provisioning
Verify Backend Deployment
Test the custom domain:
# Health check
curl https://api.altsportsleagues.ai/health | jq
# Expected: {"status":"healthy","timestamp":"..."}# API root
curl https://api.altsportsleagues.ai/ | jq
# Expected: {"message":"AltSportsLeagues API","version":"1.0.0"}# API docs
open https://api.altsportsleagues.ai/docs
# Expected: Swagger UI loads# OpenAPI schema
curl https://api.altsportsleagues.ai/openapi.json | jq '.info'
# Expected: API metadataIf all tests pass, backend is live! β
Check logs if issues:
gcloud run services logs tail altsportsleagues-backend \
--region us-central1 \
--limit 50π¨ Phase 2: Frontend Deployment
Update Configuration
Update clients/frontend/vercel.json:
{
"version": 2,
"buildCommand": "npm run build",
"framework": "nextjs",
"rewrites": [
{
"source": "/api/v1/:path*",
"destination": "https://api.altsportsleagues.ai/v1/:path*"
}
],
"redirects": [
{
"source": "/documentation/:path*",
"destination": "https://docs.altsportsleagues.ai/:path*",
"permanent": false
}
]
}Key Changes:
- β
Use custom domain (
api.altsportsleagues.ai) - β
Clean backend path (
/v1/*not/api/v1/*) - β Add redirect to docs site
Set Environment Variables
In Vercel Dashboard:
- Go to Vercel Dashboard (opens in a new tab)
- Select your frontend project
- Go to Settings β Environment Variables
- Add variables for Production environment:
NEXT_PUBLIC_API_URL=https://api.altsportsleagues.ai
BACKEND_API_URL=https://api.altsportsleagues.ai
NEXT_PUBLIC_SITE_URL=https://altsportsleagues.aiClick Save for each variable.
Deploy Frontend
Option A: Via deployment script
cd /Users/kbselander/Developer/Notebook/mcp-servers/servers/mcp-server-altsportsleagues.ai/2.1-cloud-run-docker-mcp
./deploy-all.shSelect: Option 3 (Frontend only)
Option B: Via Vercel CLI
cd clients/frontend
vercel --prodWait: 2-5 minutes for build and deployment
Map Custom Domain
In Vercel Dashboard:
- Go to your project β Settings β Domains
- Click Add Domain
- Enter:
altsportsleagues.ai - Click Add
- Vercel provides CNAME target (e.g.,
cname.vercel-dns.com)
In Cloudflare:
- Go to DNS β Records
- Add CNAME record:
- Type: CNAME
- Name:
@(oraltsportsleagues.ai) - Target:
cname.vercel-dns.com(from Vercel) - Proxy: βοΈ Proxied
- Click Save
Optional - www subdomain:
- Name:
www - Target:
cname.vercel-dns.com - Proxy: βοΈ Proxied
Wait: 1-5 minutes for DNS propagation
Verify Frontend Deployment
# Test main site
open https://altsportsleagues.ai
# Test API proxy
curl https://altsportsleagues.ai/api/v1/leagues | jq
# Should return same data as direct backend:
curl https://api.altsportsleagues.ai/v1/leagues | jqIn Browser DevTools:
- Open
https://altsportsleagues.ai - Open DevTools (F12) β Network tab
- Trigger API call (e.g., view leagues)
- Check request:
- URL shows:
/api/v1/leagues(relative) - Status: 200 OK
- No CORS errors in Console
- URL shows:
β Success: If API calls work and no errors, frontend is live!
π Phase 3: Documentation Site
Deploy Docs Site
cd apps/docs-site
# Install dependencies (if needed)
npm install
# Test build locally
npm run build
# Deploy to production
vercel --prodWait: 3-5 minutes for build
Map Custom Domain
In Vercel Dashboard (separate project for docs):
- Select the docs site project
- Settings β Domains
- Add:
docs.altsportsleagues.ai - Note CNAME target from Vercel
In Cloudflare:
- DNS β Add Record
- Configure:
- Type: CNAME
- Name:
docs - Target:
cname.vercel-dns.com(from Vercel docs project) - Proxy: βοΈ Proxied
- Save
Verify Docs Deployment
# Test docs site
open https://docs.altsportsleagues.ai
# Verify architecture pages
open https://docs.altsportsleagues.ai/architecture
# Test search
# (Use search bar in docs UI)Docs should load with full navigation, search, and interactive schema explorers!
β Phase 4: Complete Verification
Verification Checklist
Backend (api.altsportsleagues.ai):
# Health check
curl https://api.altsportsleagues.ai/health | jq
# β
Expected: {"status":"healthy"}
# API docs
open https://api.altsportsleagues.ai/docs
# β
Expected: Swagger UI loads
# API endpoint
curl https://api.altsportsleagues.ai/v1/leagues | jq
# β
Expected: JSON responseFrontend (altsportsleagues.ai):
# Main site
open https://altsportsleagues.ai
# β
Expected: Site loads, no errors
# API proxy test
curl https://altsportsleagues.ai/api/v1/leagues | jq
# β
Expected: Same data as direct backend callBrowser Console Check:
- Open DevTools (F12)
- Console tab: No CORS errors β
- Network tab: All API calls return 200 β
- Application tab: Service worker active (if PWA) β
Docs Site (docs.altsportsleagues.ai):
# Docs homepage
open https://docs.altsportsleagues.ai
# β
Expected: Docs load
# Architecture section
open https://docs.altsportsleagues.ai/architecture
# β
Expected: This page loads!
# Search functionality
# Use search in docs UI
# β
Expected: Results appearn8n (n8n.altsportsleagues.ai):
# n8n UI
open https://n8n.altsportsleagues.ai
# β
Expected: Login page or dashboard (if authenticated)
# Test webhook (if configured)
curl -X POST https://n8n.altsportsleagues.ai/webhook/test
# β
Expected: Workflow triggersπ§ Post-Deployment Configuration
CORS Configuration (Backend)
Ensure backend allows all your frontend domains:
# apps/backend/server.py
from fastapi.middleware.cors import CORSMiddleware
app.add_middleware(
CORSMiddleware,
allow_origins=[
"https://altsportsleagues.ai",
"https://www.altsportsleagues.ai",
"https://docs.altsportsleagues.ai",
"https://n8n.altsportsleagues.ai",
"https://*.vercel.app", # Preview deployments
],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)Cloudflare Security Settings
Recommended configuration:
-
SSL/TLS:
- Mode: Full (strict)
- Min TLS Version: 1.2
- Always Use HTTPS: On
-
Security:
- DDoS Protection: Auto (included)
- WAF: On (if available)
- Bot Fight Mode: On
-
Performance:
- Caching Level: Standard
- Auto Minify: JS, CSS, HTML
- Brotli: On
Health Check Monitoring
Set up alerts in Google Cloud Console:
- Go to Cloud Run β Service β Metrics
- Create alert policy:
- Metric: Request count
- Condition: > 100 5xx errors in 5 minutes
- Notification: Email/Slack
π Deployment Timeline
Estimated Duration
| Phase | Task | Duration | Dependencies |
|---|---|---|---|
| Pre-Deployment | Local testing | 15 min | Docker running |
| Backend | Cloud Run deploy | 8 min | gcloud auth |
| Backend | Domain mapping | 20 min | DNS propagation |
| Frontend | Vercel deploy | 5 min | vercel auth |
| Frontend | Domain mapping | 10 min | DNS propagation |
| Docs | Vercel deploy | 5 min | vercel auth |
| Docs | Domain mapping | 10 min | DNS propagation |
| Verification | Test all services | 15 min | All deployed |
| Total | ~90 min |
Note: Domain mapping times vary. SSL verification can take 5-30 minutes. DNS propagation is usually 1-5 minutes with Cloudflare.
π Rollback Procedures
Rollback Backend to Previous Revision:
# List revisions
gcloud run revisions list \
--service altsportsleagues-backend \
--region us-central1
# Rollback to specific revision
gcloud run services update-traffic altsportsleagues-backend \
--to-revisions REVISION_NAME=100 \
--region us-central1Check rollback:
curl https://api.altsportsleagues.ai/healthπ Monitoring & Logs
Backend Logs (Cloud Run)
# Tail logs (live)
gcloud run services logs tail altsportsleagues-backend \
--region us-central1 \
--limit 100
# Read recent logs
gcloud run services logs read altsportsleagues-backend \
--region us-central1 \
--followFrontend Logs (Vercel)
# Via CLI
vercel logs
# Or in dashboard:
# https://vercel.com/dashboard
# β Project β Deployments β Select deployment β View LogsCloudflare Analytics
Visit Cloudflare Dashboard (opens in a new tab) β Analytics:
- Total requests
- Bandwidth usage
- Threats blocked
- Cache hit rate
π Troubleshooting
Common Issues
Issue: Domain mapping stuck in "Pending Verification"
Solution: Verify DNS is correct in Cloudflare. Use dig api.altsportsleagues.ai to check.
Wait up to 30 minutes for Google to verify.
Issue: 502/503 errors from backend
Solution: Check Cloud Run logs for application errors. Verify environment variables are set. Test health endpoint directly.
Issue: CORS errors in frontend
Solution: Verify backend CORS middleware includes your frontend domain. Ensure frontend uses rewrites (not direct API calls).
Issue: SSL certificate errors
Solution: Wait for platforms to provision certificates (automatic). Force HTTPS in Cloudflare settings.
π Deployment Complete!
Your platform is now live on production URLs. Monitor the dashboards and set up alerts for any issues. See Security Architecture for best practices.