diff --git a/.env.production.example b/.env.production.example new file mode 100644 index 0000000..b965be9 --- /dev/null +++ b/.env.production.example @@ -0,0 +1,10 @@ +# Frontend Environment Variables (Production) + +# Backend API URL +VITE_BACKEND_URL=https://backend.example.com + +# Enable backend storage (set to 'false' to use IndexedDB only) +VITE_USE_BACKEND=true + +# Optional: API Key for authenticated requests +# VITE_API_KEY=your-api-key-here diff --git a/ROADMAP.md b/ROADMAP.md index dc6ecb0..31d6eae 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -305,7 +305,7 @@ CodeForge is a comprehensive low-code development platform for building producti --- ### Iteration 7: JSON-Driven Architecture Completion -**Focus:** Component registry refactor, expanding JSON page system +**Focus:** Component registry refactor, expanding JSON page system, production deployment #### Completed - ✅ Component registry refactored to read from `component-registry.json` @@ -315,6 +315,10 @@ CodeForge is a comprehensive low-code development platform for building producti - ✅ JSON-based Lambda Designer page created - ✅ Experimental flags support for components - ✅ Configurable preload strategies per component +- ✅ CapRover/Cloudflare CORS configuration +- ✅ Production deployment documentation +- ✅ Environment variable templates for frontend and backend +- ✅ Deployment checklist and troubleshooting guides #### Benefits Achieved - **Zero code changes** needed to add new components to registry @@ -322,12 +326,18 @@ CodeForge is a comprehensive low-code development platform for building producti - **Runtime flexibility** for enabling/disabling components - **Better performance** with configurable lazy loading - **Improved maintainability** with declarative component definitions +- **Production-ready deployment** with proper CORS and security configuration #### Key Files - `component-registry.json` - Centralized component metadata - `src/lib/component-registry.ts` - Dynamic registry loader - `src/components/JSONLambdaDesigner.tsx` - New JSON-based Lambda page - `src/config/pages/lambda-designer.json` - Lambda page schema +- `nginx.conf` - Updated with CORS headers +- `backend/app.py` - Enhanced Flask CORS configuration +- `docs/CAPROVER_CLOUDFLARE_DEPLOYMENT.md` - Complete deployment guide +- `docs/CLOUDFLARE_CONFIGURATION.md` - Cloudflare setup guide +- `docs/DEPLOYMENT_CHECKLIST.md` - Quick reference checklist --- @@ -366,7 +376,48 @@ CodeForge is a comprehensive low-code development platform for building producti ### Near-Term (Next 2-3 Iterations) -#### 1. Complete JSON Migration +#### 1. CapRover/Cloudflare CORS Configuration +**Priority:** HIGH +**Effort:** LOW +**Status:** ✅ COMPLETE + +**Completed:** +- ✅ Updated nginx.conf with proper CORS headers for frontend +- ✅ Enhanced Flask backend with detailed CORS configuration +- ✅ Created comprehensive deployment documentation +- ✅ Added environment variable examples for production +- ✅ Created CapRover captain-definition files +- ✅ Documented Cloudflare configuration steps +- ✅ Created deployment checklist +- ✅ Added CORS testing procedures + +**Files Created:** +- `docs/CAPROVER_CLOUDFLARE_DEPLOYMENT.md` - Complete deployment guide +- `docs/CLOUDFLARE_CONFIGURATION.md` - Cloudflare-specific settings +- `docs/DEPLOYMENT_CHECKLIST.md` - Quick deployment checklist +- `.env.production.example` - Frontend environment template +- `backend/.env.production.example` - Backend environment template +- `captain-definition` - CapRover frontend config +- `backend/captain-definition` - CapRover backend config + +**Configuration Details:** +- Frontend nginx handles CORS headers for SPA routes and assets +- Backend Flask-CORS configured for cross-origin API requests +- Support for multiple allowed origins via environment variables +- Preflight OPTIONS request handling +- Credentials support for authenticated requests +- Security headers and rate limiting guidance + +**Benefits:** +- ✅ Proper CORS configuration for frontend/backend separation +- ✅ Support for https://frontend.example.com + https://backend.example.com architecture +- ✅ Easy deployment to CapRover with Cloudflare CDN +- ✅ Production-ready security configuration +- ✅ Comprehensive troubleshooting documentation + +--- + +#### 2. Complete JSON Migration **Priority:** HIGH **Effort:** MEDIUM **Status:** IN PROGRESS diff --git a/backend/.env.production.example b/backend/.env.production.example new file mode 100644 index 0000000..45720b3 --- /dev/null +++ b/backend/.env.production.example @@ -0,0 +1,20 @@ +# Backend Environment Variables (Production) + +# Allowed CORS origins (comma-separated) +# Use your actual frontend domain(s) +ALLOWED_ORIGINS=https://frontend.example.com,https://www.frontend.example.com + +# Server Port +PORT=5001 + +# Database path (use /data for persistent CapRover volume) +DATABASE_PATH=/data/codeforge.db + +# Debug mode (set to 'false' in production) +DEBUG=false + +# Optional: API Key for authentication +# API_KEY=your-secure-api-key-here + +# Optional: Rate limiting +# RATELIMIT_STORAGE_URL=redis://localhost:6379 diff --git a/backend/app.py b/backend/app.py index 1e297d6..c677c4a 100644 --- a/backend/app.py +++ b/backend/app.py @@ -7,7 +7,20 @@ from datetime import datetime from contextlib import contextmanager app = Flask(__name__) -CORS(app) + +# CORS configuration for CapRover/Cloudflare deployment +# Allow requests from frontend domain +ALLOWED_ORIGINS = os.environ.get('ALLOWED_ORIGINS', '*').split(',') +CORS(app, + resources={r"/api/*": { + "origins": ALLOWED_ORIGINS, + "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"], + "allow_headers": ["Content-Type", "Authorization", "X-Requested-With"], + "expose_headers": ["Content-Type", "X-Total-Count"], + "supports_credentials": True, + "max_age": 3600 + }}, + supports_credentials=True) DATABASE_PATH = os.environ.get('DATABASE_PATH', '/data/codeforge.db') os.makedirs(os.path.dirname(DATABASE_PATH), exist_ok=True) diff --git a/backend/captain-definition b/backend/captain-definition new file mode 100644 index 0000000..dc9062c --- /dev/null +++ b/backend/captain-definition @@ -0,0 +1,5 @@ +{ + "schemaVersion": 2, + "dockerfilePath": "./Dockerfile", + "dockerfileLines": [] +} diff --git a/captain-definition b/captain-definition new file mode 100644 index 0000000..dc9062c --- /dev/null +++ b/captain-definition @@ -0,0 +1,5 @@ +{ + "schemaVersion": 2, + "dockerfilePath": "./Dockerfile", + "dockerfileLines": [] +} diff --git a/docs/CAPROVER_CLOUDFLARE_DEPLOYMENT.md b/docs/CAPROVER_CLOUDFLARE_DEPLOYMENT.md new file mode 100644 index 0000000..32fc0f0 --- /dev/null +++ b/docs/CAPROVER_CLOUDFLARE_DEPLOYMENT.md @@ -0,0 +1,388 @@ +# CapRover & Cloudflare CORS Configuration Guide + +This guide covers deploying CodeForge with separate frontend and backend domains, properly configured for CORS. + +## Architecture + +``` +Frontend: https://frontend.example.com (nginx serving React SPA) +Backend: https://backend.example.com (Flask API) +``` + +## Frontend Configuration + +### 1. Nginx CORS Setup + +The `nginx.conf` has been configured with proper CORS headers: + +- **Access-Control-Allow-Origin**: Allows all origins (can be restricted) +- **Access-Control-Allow-Methods**: GET, POST, PUT, DELETE, OPTIONS +- **Access-Control-Allow-Headers**: All necessary headers including Authorization +- **Preflight Handling**: OPTIONS requests are handled with 204 response + +### 2. CapRover Frontend Setup + +Create a new app in CapRover for the frontend: + +```bash +# App Settings +App Name: codeforge-frontend +Deployment Method: Docker Image Registry or Git +Port: 80 +``` + +#### Environment Variables (Optional) +```env +# If you need to configure backend URL at build time +VITE_BACKEND_URL=https://backend.example.com +``` + +#### Captain Definition File +Create `captain-definition` in project root: +```json +{ + "schemaVersion": 2, + "dockerfilePath": "./Dockerfile" +} +``` + +### 3. Cloudflare Settings for Frontend + +1. **SSL/TLS Mode**: Full (strict) or Full +2. **Always Use HTTPS**: Enabled +3. **Minimum TLS Version**: TLS 1.2 +4. **Automatic HTTPS Rewrites**: Enabled + +#### Security Headers (Optional but Recommended) +Go to Cloudflare Dashboard → Security → Settings → Security Headers: + +``` +Strict-Transport-Security: max-age=31536000; includeSubDomains +X-Content-Type-Options: nosniff +X-Frame-Options: SAMEORIGIN +``` + +**Note**: Don't add CORS headers in Cloudflare if nginx is already handling them. + +## Backend Configuration + +### 1. Flask CORS Setup + +The backend has been configured with `flask-cors`: + +```python +ALLOWED_ORIGINS = os.environ.get('ALLOWED_ORIGINS', '*').split(',') +CORS(app, + resources={r"/api/*": { + "origins": ALLOWED_ORIGINS, + "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"], + "allow_headers": ["Content-Type", "Authorization", "X-Requested-With"], + "expose_headers": ["Content-Type", "X-Total-Count"], + "supports_credentials": True, + "max_age": 3600 + }}) +``` + +### 2. CapRover Backend Setup + +Create a new app in CapRover for the backend: + +```bash +# App Settings +App Name: codeforge-backend +Deployment Method: Docker Image Registry or Git +Port: 5001 (or as configured) +``` + +#### Environment Variables +```env +# Required +ALLOWED_ORIGINS=https://frontend.example.com,https://www.frontend.example.com + +# Optional +PORT=5001 +DATABASE_PATH=/data/codeforge.db +DEBUG=false +``` + +#### Persistent Data Volume +Enable persistent storage for SQLite database: +``` +Container Path: /data +Host Path: /captain/data/codeforge-backend +``` + +#### Captain Definition File for Backend +Create `backend/captain-definition`: +```json +{ + "schemaVersion": 2, + "dockerfilePath": "./Dockerfile" +} +``` + +### 3. Cloudflare Settings for Backend + +1. **SSL/TLS Mode**: Full (strict) or Full +2. **Always Use HTTPS**: Enabled +3. **Minimum TLS Version**: TLS 1.2 +4. **API Shield** (if available): Enable for API endpoints + +## Frontend Code Configuration + +### Environment-based Backend URL + +Create `.env.production`: +```env +VITE_BACKEND_URL=https://backend.example.com +VITE_USE_BACKEND=true +``` + +### Runtime Configuration + +The app auto-detects backend availability. Update your storage configuration: + +```typescript +// src/lib/storage-config.ts +const BACKEND_URL = import.meta.env.VITE_BACKEND_URL || + window.RUNTIME_CONFIG?.backendUrl || + 'http://localhost:5001' + +const USE_BACKEND = import.meta.env.VITE_USE_BACKEND === 'true' || + window.RUNTIME_CONFIG?.useBackend === true +``` + +## Testing CORS Configuration + +### 1. Test Frontend CORS + +```bash +curl -X OPTIONS https://frontend.example.com \ + -H "Origin: https://other-domain.com" \ + -H "Access-Control-Request-Method: GET" \ + -v +``` + +Expected response should include: +``` +Access-Control-Allow-Origin: * +Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS +``` + +### 2. Test Backend CORS + +```bash +curl -X OPTIONS https://backend.example.com/api/storage/keys \ + -H "Origin: https://frontend.example.com" \ + -H "Access-Control-Request-Method: GET" \ + -v +``` + +Expected response should include: +``` +Access-Control-Allow-Origin: https://frontend.example.com +Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS +Access-Control-Allow-Credentials: true +``` + +### 3. Test Cross-Origin Request + +```bash +curl -X GET https://backend.example.com/api/storage/keys \ + -H "Origin: https://frontend.example.com" \ + -v +``` + +## Common Issues & Solutions + +### Issue 1: CORS Error in Browser Console + +**Error**: `No 'Access-Control-Allow-Origin' header is present` + +**Solutions**: +1. Verify `ALLOWED_ORIGINS` environment variable is set correctly on backend +2. Check nginx config is properly loaded (restart CapRover app) +3. Ensure Cloudflare is not stripping CORS headers + +### Issue 2: Preflight Request Failing + +**Error**: `Response to preflight request doesn't pass access control check` + +**Solutions**: +1. Verify OPTIONS method is allowed in both nginx and Flask +2. Check that preflight response includes all required headers +3. Increase `max_age` if requests are frequent + +### Issue 3: Credentials Not Sent + +**Error**: Cookies/credentials not sent with request + +**Solutions**: +1. Enable `credentials: 'include'` in fetch requests +2. Set `supports_credentials: True` in Flask CORS config +3. Don't use wildcard `*` for origin when credentials are needed + +### Issue 4: Cloudflare Blocking Requests + +**Error**: `CF-RAY` header present with 403/520 errors + +**Solutions**: +1. Whitelist your backend domain in Cloudflare Firewall +2. Disable "Browser Integrity Check" temporarily for testing +3. Check Cloudflare Security Level (set to "Low" for API endpoints) + +## Security Best Practices + +### 1. Restrict Origins in Production + +Instead of `*`, specify exact origins: + +```env +# Backend .env +ALLOWED_ORIGINS=https://frontend.example.com,https://www.frontend.example.com +``` + +### 2. Use HTTPS Only + +Ensure all requests use HTTPS. Update nginx to redirect HTTP to HTTPS: + +```nginx +server { + listen 80; + server_name _; + return 301 https://$host$request_uri; +} +``` + +### 3. Implement Rate Limiting + +Add rate limiting to backend: + +```python +from flask_limiter import Limiter +from flask_limiter.util import get_remote_address + +limiter = Limiter( + app=app, + key_func=get_remote_address, + default_limits=["200 per hour", "50 per minute"] +) + +@app.route('/api/storage/', methods=['GET']) +@limiter.limit("100 per minute") +def get_value(key): + # ... +``` + +### 4. Add API Authentication + +For production, add token-based authentication: + +```python +from functools import wraps +from flask import request + +def require_api_key(f): + @wraps(f) + def decorated_function(*args, **kwargs): + api_key = request.headers.get('Authorization') + if not api_key or not verify_api_key(api_key): + return jsonify({'error': 'Unauthorized'}), 401 + return f(*args, **kwargs) + return decorated_function + +@app.route('/api/storage/', methods=['PUT']) +@require_api_key +def set_value(key): + # ... +``` + +## CapRover Deployment Steps + +### Deploy Frontend + +1. Ensure Docker image builds successfully locally +2. Push code to Git repository or Docker registry +3. In CapRover: + - Create new app: `codeforge-frontend` + - Enable HTTPS + - Connect custom domain: `frontend.example.com` + - Deploy from Git/Registry + - Verify deployment via browser + +### Deploy Backend + +1. Build and test backend Docker image +2. In CapRover: + - Create new app: `codeforge-backend` + - Enable HTTPS + - Connect custom domain: `backend.example.com` + - Add environment variables (especially `ALLOWED_ORIGINS`) + - Add persistent volume at `/data` + - Deploy from Git/Registry + - Verify health endpoint: `https://backend.example.com/health` + +### Configure Cloudflare + +1. Add DNS records for both domains (point to CapRover server) +2. Enable Cloudflare proxy (orange cloud) +3. Configure SSL/TLS settings +4. Test both domains + +## Monitoring & Debugging + +### Check Nginx Logs (Frontend) +```bash +# In CapRover app terminal +tail -f /var/log/nginx/access.log +tail -f /var/log/nginx/error.log +``` + +### Check Flask Logs (Backend) +```bash +# In CapRover app logs view or terminal +tail -f /var/log/app.log +``` + +### Browser DevTools +1. Open Network tab +2. Enable "Preserve log" +3. Filter by domain to see cross-origin requests +4. Check Response headers for CORS headers +5. Look for preflight (OPTIONS) requests + +## Example Fetch Configuration + +### Frontend API Client + +```typescript +const API_BASE_URL = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5001' + +async function apiRequest(endpoint: string, options: RequestInit = {}) { + const response = await fetch(`${API_BASE_URL}${endpoint}`, { + ...options, + credentials: 'include', // Include cookies if needed + headers: { + 'Content-Type': 'application/json', + ...options.headers, + }, + }) + + if (!response.ok) { + throw new Error(`API error: ${response.statusText}`) + } + + return response.json() +} + +// Usage +const data = await apiRequest('/api/storage/keys') +``` + +## Additional Resources + +- [CapRover Documentation](https://caprover.com/docs/) +- [Cloudflare SSL/TLS Documentation](https://developers.cloudflare.com/ssl/) +- [Flask-CORS Documentation](https://flask-cors.readthedocs.io/) +- [MDN CORS Guide](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) +- [Nginx CORS Configuration](https://enable-cors.org/server_nginx.html) diff --git a/docs/CLOUDFLARE_CONFIGURATION.md b/docs/CLOUDFLARE_CONFIGURATION.md new file mode 100644 index 0000000..f907551 --- /dev/null +++ b/docs/CLOUDFLARE_CONFIGURATION.md @@ -0,0 +1,374 @@ +# Cloudflare Configuration for CodeForge + +This document outlines the recommended Cloudflare settings for deploying CodeForge with CapRover. + +## DNS Configuration + +### Frontend Domain +``` +Type: A +Name: frontend (or @) +IPv4: +Proxy status: Proxied (orange cloud) +TTL: Auto +``` + +### Backend Domain +``` +Type: A +Name: backend (or api) +IPv4: +Proxy status: Proxied (orange cloud) +TTL: Auto +``` + +### Optional: WWW Subdomain +``` +Type: CNAME +Name: www +Target: frontend.example.com +Proxy status: Proxied (orange cloud) +TTL: Auto +``` + +## SSL/TLS Settings + +Navigate to: **SSL/TLS** → **Overview** + +### Encryption Mode +- **Recommended**: Full (strict) +- **Alternative**: Full +- **Never use**: Flexible (breaks HTTPS to origin) + +### Edge Certificates +Navigate to: **SSL/TLS** → **Edge Certificates** + +- ✅ **Always Use HTTPS**: On +- ✅ **HTTP Strict Transport Security (HSTS)**: Enable + - Max Age: 12 months + - Include subdomains: Yes + - Preload: Yes (optional, but recommended) +- ✅ **Minimum TLS Version**: TLS 1.2 +- ✅ **Opportunistic Encryption**: On +- ✅ **TLS 1.3**: On +- ✅ **Automatic HTTPS Rewrites**: On +- ✅ **Certificate Transparency Monitoring**: On + +## Firewall Rules + +Navigate to: **Security** → **WAF** → **Firewall rules** + +### Rule 1: Allow Backend API Requests +``` +Rule name: Allow API Access +Expression: + (http.host eq "backend.example.com" and http.request.uri.path starts_with "/api/") +Action: Allow +``` + +### Rule 2: Rate Limit (Optional) +``` +Rule name: API Rate Limit +Expression: + (http.host eq "backend.example.com" and http.request.uri.path starts_with "/api/") +Action: Rate Limit +Requests: 100 requests per minute +Duration: 1 minute +``` + +## Page Rules + +Navigate to: **Rules** → **Page Rules** + +### Rule 1: Backend API Caching +``` +URL: backend.example.com/api/* +Settings: + - Cache Level: Bypass + - Security Level: Medium + - Browser Integrity Check: Off (for API) +``` + +### Rule 2: Frontend Caching +``` +URL: frontend.example.com/* +Settings: + - Cache Level: Standard + - Browser Cache TTL: 4 hours + - Edge Cache TTL: 2 hours +``` + +### Rule 3: Frontend Assets Caching +``` +URL: frontend.example.com/assets/* +Settings: + - Cache Level: Cache Everything + - Edge Cache TTL: 1 month + - Browser Cache TTL: 1 month +``` + +## Speed Settings + +Navigate to: **Speed** → **Optimization** + +### Auto Minify +- ✅ JavaScript +- ✅ CSS +- ✅ HTML + +### Brotli +- ✅ On + +### Rocket Loader +- ⚠️ Off (can break SPA) + +### Mirage +- ⚠️ Off (for modern SPAs) + +### Polish +- Optional: Lossy or Lossless (for images) + +## Network Settings + +Navigate to: **Network** + +### HTTP/3 (with QUIC) +- ✅ On + +### HTTP/2 +- ✅ On + +### 0-RTT Connection Resumption +- ✅ On + +### WebSockets +- ✅ On (required for backend WebSocket connections if used) + +### gRPC +- Optional: On (if using gRPC) + +## Caching Configuration + +Navigate to: **Caching** → **Configuration** + +### Caching Level +- Standard + +### Browser Cache TTL +- 4 hours (adjust as needed) + +### Always Online +- ✅ On (serves cached version when origin is down) + +### Development Mode +- Use temporarily during testing (disables caching for 3 hours) + +## Transform Rules (for CORS Headers) + +Navigate to: **Rules** → **Transform Rules** → **Modify Response Header** + +⚠️ **Important**: Only add these if nginx is NOT handling CORS headers. + +### Add CORS Headers to Frontend +``` +Rule name: Frontend CORS Headers +Expression: http.host eq "frontend.example.com" +Actions: + Set dynamic header: + - Header name: Access-Control-Allow-Origin + - Value: * + Set static header: + - Header name: Access-Control-Allow-Methods + - Value: GET, POST, PUT, DELETE, OPTIONS + Set static header: + - Header name: Access-Control-Allow-Headers + - Value: Content-Type, Authorization +``` + +### Add CORS Headers to Backend +``` +Rule name: Backend CORS Headers +Expression: http.host eq "backend.example.com" +Actions: + Set dynamic header: + - Header name: Access-Control-Allow-Origin + - Value: https://frontend.example.com + Set static header: + - Header name: Access-Control-Allow-Methods + - Value: GET, POST, PUT, DELETE, OPTIONS + Set static header: + - Header name: Access-Control-Allow-Credentials + - Value: true +``` + +## Security Settings + +Navigate to: **Security** → **Settings** + +### Security Level +- Medium (for production) +- Low (for testing/development) + +### Challenge Passage +- 30 minutes + +### Browser Integrity Check +- ✅ On (for frontend) +- ⚠️ Off (for backend API to avoid blocking legitimate API clients) + +### Privacy Pass Support +- ✅ On + +## DDoS Protection + +Navigate to: **Security** → **DDoS** + +- Managed by Cloudflare automatically +- No configuration needed +- Monitor attacks in dashboard + +## Bot Management (Enterprise/Business Plans) + +Navigate to: **Security** → **Bots** + +### Bot Fight Mode (Free/Pro/Business) +- ⚠️ Off for API endpoints (can block legitimate requests) +- ✅ On for frontend (protects against scrapers) + +### Super Bot Fight Mode (Business+) +- Configure to allow verified bots +- Block definitely automated traffic + +## Analytics & Monitoring + +### Web Analytics +Navigate to: **Analytics & Logs** → **Web Analytics** +- Enable to track frontend traffic + +### Health Checks +Navigate to: **Traffic** → **Health Checks** + +#### Frontend Health Check +``` +Name: Frontend Health +URL: https://frontend.example.com/health +Type: HTTPS +Method: GET +Expected Status: 200 +Interval: 60 seconds +``` + +#### Backend Health Check +``` +Name: Backend Health +URL: https://backend.example.com/health +Type: HTTPS +Method: GET +Expected Status: 200 +Interval: 60 seconds +``` + +## Origin Rules (for CapRover) + +Navigate to: **Rules** → **Origin Rules** + +### Set Origin to CapRover +``` +Rule name: Forward to CapRover +Expression: http.host in {"frontend.example.com" "backend.example.com"} +Actions: + - Override origin: + - Override port: 443 +``` + +## Testing Cloudflare Configuration + +### 1. Verify SSL +```bash +curl -I https://frontend.example.com +# Should return: HTTP/2 200 +# Check for: strict-transport-security header +``` + +### 2. Verify CORS +```bash +curl -X OPTIONS https://backend.example.com/api/storage/keys \ + -H "Origin: https://frontend.example.com" \ + -H "Access-Control-Request-Method: GET" \ + -v +``` + +### 3. Check Caching +```bash +curl -I https://frontend.example.com/assets/index.js +# Should return: cf-cache-status: HIT (after first request) +``` + +### 4. Test Rate Limiting +```bash +# Run multiple times quickly +for i in {1..150}; do + curl https://backend.example.com/api/storage/keys +done +# Should eventually get rate limited +``` + +## Troubleshooting + +### Issue: 520/521/522 Errors + +**Cause**: Cloudflare can't connect to origin server + +**Solutions**: +1. Verify CapRover server is running +2. Check firewall allows Cloudflare IPs +3. Verify SSL certificate on origin +4. Check Cloudflare SSL mode is not "Flexible" + +### Issue: CORS Errors Still Occurring + +**Cause**: Conflicting CORS headers from multiple sources + +**Solutions**: +1. Remove CORS headers from Cloudflare Transform Rules if nginx handles them +2. Check both nginx and Flask CORS configs +3. Use browser DevTools to see which headers are present + +### Issue: Assets Not Caching + +**Cause**: Cache rules not properly configured + +**Solutions**: +1. Verify page rules are in correct order (more specific first) +2. Check cache level is appropriate +3. Enable Development Mode temporarily to bypass cache +4. Purge cache and retry + +### Issue: API Requests Being Blocked + +**Cause**: Bot Fight Mode or firewall rules + +**Solutions**: +1. Disable Bot Fight Mode for backend domain +2. Check firewall events for blocked requests +3. Whitelist your IP or API client user-agent +4. Disable Browser Integrity Check for API + +## Recommended Setup Order + +1. ✅ Set up DNS records (A records for both domains) +2. ✅ Configure SSL/TLS (Full or Full Strict mode) +3. ✅ Enable HTTPS redirects and HSTS +4. ✅ Configure firewall rules (if needed) +5. ✅ Set up page rules for caching +6. ✅ Configure health checks +7. ✅ Enable speed optimizations +8. ✅ Test thoroughly before going live +9. ✅ Monitor analytics and logs + +## Additional Resources + +- [Cloudflare Support](https://support.cloudflare.com/) +- [Cloudflare Community](https://community.cloudflare.com/) +- [Cloudflare Developers Docs](https://developers.cloudflare.com/) +- [Cloudflare Status](https://www.cloudflarestatus.com/) diff --git a/docs/DEPLOYMENT_CHECKLIST.md b/docs/DEPLOYMENT_CHECKLIST.md new file mode 100644 index 0000000..dc0de45 --- /dev/null +++ b/docs/DEPLOYMENT_CHECKLIST.md @@ -0,0 +1,244 @@ +# CapRover/Cloudflare Deployment Checklist + +Quick reference guide for deploying CodeForge to CapRover with Cloudflare. + +## Pre-Deployment + +- [ ] CapRover server is running and accessible +- [ ] Domains registered and pointing to Cloudflare nameservers +- [ ] Docker is installed locally (for testing builds) +- [ ] Git repository is ready for deployment + +## Frontend Deployment + +### 1. Configuration +- [ ] Copy `.env.production.example` to `.env.production` +- [ ] Update `VITE_BACKEND_URL` with your backend domain +- [ ] Update `VITE_USE_BACKEND=true` if using backend + +### 2. CapRover App Setup +- [ ] Create new app: `codeforge-frontend` +- [ ] Enable HTTPS in CapRover app settings +- [ ] Connect custom domain: `frontend.example.com` +- [ ] Configure environment variables (if any) + +### 3. Deploy +- [ ] Push code to Git repository +- [ ] Deploy via CapRover (Git/Registry/Upload) +- [ ] Wait for build to complete +- [ ] Check build logs for errors + +### 4. Verify +- [ ] Visit `https://frontend.example.com` +- [ ] Check browser console for errors +- [ ] Verify assets load correctly +- [ ] Test app functionality + +## Backend Deployment + +### 1. Configuration +- [ ] Copy `backend/.env.production.example` to `backend/.env.production` +- [ ] Update `ALLOWED_ORIGINS` with frontend domains +- [ ] Set `DEBUG=false` for production +- [ ] Configure `DATABASE_PATH=/data/codeforge.db` + +### 2. CapRover App Setup +- [ ] Create new app: `codeforge-backend` +- [ ] Enable HTTPS in CapRover app settings +- [ ] Connect custom domain: `backend.example.com` +- [ ] Add environment variables: + - [ ] `ALLOWED_ORIGINS=https://frontend.example.com` + - [ ] `PORT=5001` + - [ ] `DATABASE_PATH=/data/codeforge.db` + - [ ] `DEBUG=false` +- [ ] Configure persistent volume: + - [ ] Container path: `/data` + - [ ] Label: `backend-data` + +### 3. Deploy +- [ ] Deploy backend via CapRover +- [ ] Wait for build to complete +- [ ] Check build logs for errors + +### 4. Verify +- [ ] Visit `https://backend.example.com/health` +- [ ] Should return: `{"status": "ok", "timestamp": "..."}` +- [ ] Test API endpoint: `https://backend.example.com/api/storage/keys` +- [ ] Check response includes CORS headers + +## Cloudflare Configuration + +### DNS +- [ ] Add A record for frontend pointing to CapRover server IP +- [ ] Add A record for backend pointing to CapRover server IP +- [ ] Enable proxy (orange cloud) for both records + +### SSL/TLS +- [ ] Set encryption mode to "Full (strict)" or "Full" +- [ ] Enable "Always Use HTTPS" +- [ ] Enable HSTS (optional but recommended) +- [ ] Set minimum TLS version to 1.2 + +### Speed & Caching +- [ ] Enable Auto Minify (JS, CSS, HTML) +- [ ] Enable Brotli compression +- [ ] Disable Rocket Loader (can break SPA) +- [ ] Configure page rules: + - [ ] Backend API: Cache Level = Bypass + - [ ] Frontend: Cache Level = Standard + - [ ] Frontend Assets: Cache Everything, TTL = 1 month + +### Security +- [ ] Set security level to "Medium" +- [ ] Disable "Browser Integrity Check" for backend +- [ ] Configure firewall rules (if needed) +- [ ] Set up rate limiting (optional) + +### Health Checks +- [ ] Add health check for frontend: `https://frontend.example.com/health` +- [ ] Add health check for backend: `https://backend.example.com/health` + +## Testing + +### CORS Testing +```bash +# Test backend CORS +curl -X OPTIONS https://backend.example.com/api/storage/keys \ + -H "Origin: https://frontend.example.com" \ + -H "Access-Control-Request-Method: GET" \ + -v + +# Expected: Access-Control-Allow-Origin header in response +``` + +### SSL Testing +```bash +# Test SSL +curl -I https://frontend.example.com +curl -I https://backend.example.com + +# Expected: HTTP/2 200 with security headers +``` + +### Functionality Testing +- [ ] Open frontend in browser +- [ ] Open DevTools → Network tab +- [ ] Test creating/reading/updating data +- [ ] Verify API calls to backend succeed +- [ ] Check for CORS errors in console +- [ ] Test on multiple browsers (Chrome, Firefox, Safari) +- [ ] Test on mobile devices + +### Performance Testing +- [ ] Run Lighthouse audit on frontend +- [ ] Check page load times +- [ ] Verify assets are cached (cf-cache-status: HIT) +- [ ] Test from multiple geographic locations + +## Post-Deployment + +### Monitoring +- [ ] Set up Cloudflare alerts for downtime +- [ ] Monitor CapRover logs for errors +- [ ] Check health endpoints regularly +- [ ] Review Cloudflare Analytics + +### Backups +- [ ] Verify database backups are working +- [ ] Test database restore procedure +- [ ] Export project data via API +- [ ] Document backup schedule + +### Documentation +- [ ] Document custom configuration +- [ ] Update team on deployment URLs +- [ ] Create runbook for common issues +- [ ] Document rollback procedure + +## Rollback Procedure + +If deployment fails: + +1. [ ] Check CapRover logs for errors +2. [ ] Review Cloudflare Firewall events +3. [ ] Disable Cloudflare proxy temporarily (gray cloud) +4. [ ] Test direct connection to CapRover server +5. [ ] Revert to previous Docker image +6. [ ] Re-enable Cloudflare proxy after fix + +## Common Issues + +### Frontend loads but API calls fail +- Check CORS configuration in backend +- Verify `ALLOWED_ORIGINS` environment variable +- Check Cloudflare firewall isn't blocking requests +- Verify backend domain is accessible + +### 502/520 Errors +- Check CapRover app is running +- Verify SSL certificates are valid +- Check Cloudflare SSL mode (should be Full or Full Strict) +- Verify origin server accepts connections on port 443 + +### Assets not loading +- Check nginx configuration is correct +- Verify Vite build completed successfully +- Check Cloudflare caching rules +- Purge Cloudflare cache and retry + +### Database not persisting +- Verify persistent volume is mounted +- Check `DATABASE_PATH` environment variable +- Verify `/data` directory has write permissions +- Check CapRover volume configuration + +## Quick Reference + +### Frontend URL +``` +https://frontend.example.com +``` + +### Backend URL +``` +https://backend.example.com +``` + +### Health Endpoints +``` +Frontend: https://frontend.example.com/health +Backend: https://backend.example.com/health +``` + +### API Base URL +``` +https://backend.example.com/api +``` + +### CapRover Apps +``` +Frontend: codeforge-frontend +Backend: codeforge-backend +``` + +## Support Resources + +- **CapRover Docs**: https://caprover.com/docs/ +- **Cloudflare Docs**: https://developers.cloudflare.com/ +- **Project Docs**: `/docs/CAPROVER_CLOUDFLARE_DEPLOYMENT.md` +- **Cloudflare Config**: `/docs/CLOUDFLARE_CONFIGURATION.md` + +## Emergency Contacts + +Document your team's contact information: + +- DevOps Lead: _____________ +- Backend Developer: _____________ +- Frontend Developer: _____________ +- CapRover Admin: _____________ + +--- + +**Last Updated**: [Date] +**Deployed By**: [Name] +**Deployment Date**: [Date] diff --git a/nginx.conf b/nginx.conf index f3c173d..640491b 100644 --- a/nginx.conf +++ b/nginx.conf @@ -7,6 +7,23 @@ server { location / { try_files $uri $uri/ /index.html; + + # CORS headers for frontend + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always; + add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range' always; + + # Handle preflight requests + if ($request_method = 'OPTIONS') { + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization' always; + add_header 'Access-Control-Max-Age' 1728000; + add_header 'Content-Type' 'text/plain; charset=utf-8'; + add_header 'Content-Length' 0; + return 204; + } } location /health { @@ -18,6 +35,11 @@ server { location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ { expires 1y; add_header Cache-Control "public, immutable"; + + # CORS for assets + add_header 'Access-Control-Allow-Origin' '*' always; + add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS' always; + add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range' always; } gzip on;