Files
mylder-frontend/docs/cloudflare-setup.md
christiankrag ef31ed3564 Add health endpoint for Swarm health checks
The /health route returns JSON status for Docker Swarm
to verify container health during deployment.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 13:27:25 +01:00

381 lines
9.0 KiB
Markdown

# Cloudflare Setup for Mylder Platform
## Overview
Cloudflare configuration for https://mylder.io - Next.js 16 frontend with self-hosted backend (Supabase, n8n) via Dokploy/Traefik.
**VPS:** 149.102.155.84
**Stack:** Next.js 16 → Traefik → Cloudflare CDN
## DNS Configuration
### Step 1: Add Domain to Cloudflare
1. Cloudflare Dashboard → Add Site → mylder.io
2. Update nameservers at domain registrar to Cloudflare's nameservers
### Step 2: DNS Records
| Type | Name | Target | Proxy Status | Notes |
|------|------|--------|--------------|-------|
| A | @ | 149.102.155.84 | Proxied (orange cloud) | Main site |
| A | www | 149.102.155.84 | Proxied | WWW redirect |
| A | dokploy | 149.102.155.84 | DNS Only (grey cloud) | Dokploy dashboard - skip CDN |
| A | supabase | 149.102.155.84 | DNS Only | Supabase API - skip CDN |
| A | n8n | 149.102.155.84 | DNS Only | n8n webhooks - skip CDN |
| A | gitea | 149.102.155.84 | DNS Only | Git push/pull - skip CDN |
| A | saas | 149.102.155.84 | DNS Only | Zulip chat - skip CDN |
**Key Principle:**
- **Proxied (CDN):** Frontend, static assets, public content
- **DNS Only:** Admin tools, APIs with authentication, real-time services
### Step 3: Subdomain Wildcard (Optional)
If you need dynamic subdomains (e.g., tenant.mylder.io):
```
CNAME * @ (Proxied)
```
## SSL/TLS Settings
### Encryption Mode: Full (Strict)
**Path:** SSL/TLS → Overview → Full (strict)
**Why:** Traefik already provides Let's Encrypt certificates. Full (strict) ensures end-to-end encryption:
```
Browser → Cloudflare (encrypted) → Traefik (encrypted) → App
```
### Edge Certificates
**Path:** SSL/TLS → Edge Certificates
- **Always Use HTTPS:** ON
- **Minimum TLS Version:** 1.2
- **Opportunistic Encryption:** ON
- **TLS 1.3:** ON
- **Automatic HTTPS Rewrites:** ON
- **Certificate Transparency Monitoring:** ON
### Origin Server
**Path:** SSL/TLS → Origin Server
No action needed - Traefik manages Let's Encrypt certificates automatically.
## Caching Rules
### Default Cache Levels
**Path:** Caching → Configuration
- **Caching Level:** Standard
- **Browser Cache TTL:** Respect Existing Headers
- **Always Online:** ON (serves stale content if origin is down)
### Cache Rules for Next.js
**Path:** Rules → Page Rules (legacy) or Cache Rules (new)**
#### Rule 1: Static Assets (Aggressive Caching)
```
URL Pattern: mylder.io/_next/static/*
Settings:
- Cache Level: Cache Everything
- Edge Cache TTL: 1 year
- Browser Cache TTL: 1 year
```
#### Rule 2: Images (Smart Caching)
```
URL Pattern: mylder.io/_next/image/*
Settings:
- Cache Level: Cache Everything
- Edge Cache TTL: 30 days
- Browser Cache TTL: 7 days
```
#### Rule 3: API Routes (No Cache)
```
URL Pattern: mylder.io/api/*
Settings:
- Cache Level: Bypass
```
#### Rule 4: Dynamic Pages (Smart Cache)
```
URL Pattern: mylder.io/*
Settings:
- Cache Level: Standard
- Edge Cache TTL: 2 hours
- Browser Cache TTL: 30 minutes
```
### Next.js Cache Headers
Ensure your Next.js app sets proper headers:
```typescript
// next.config.ts
const nextConfig = {
async headers() {
return [
{
source: '/_next/static/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
{
source: '/_next/image/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=2592000, stale-while-revalidate=86400',
},
],
},
];
},
};
```
### Cache Purge Strategy
**Path:** Caching → Configuration → Purge Cache
- **On Deploy:** Purge Everything (via API or Dashboard)
- **On Content Update:** Purge by Tag/URL
- **Emergency:** Purge Everything button
**API Purge (for CI/CD):**
```bash
curl -X POST "https://api.cloudflare.com/client/v4/zones/{zone_id}/purge_cache" \
-H "Authorization: Bearer {api_token}" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
```
## Speed Optimization
### Auto Minify
**Path:** Speed → Optimization
- **JavaScript:** ON
- **CSS:** ON
- **HTML:** ON
### Brotli Compression
**Path:** Speed → Optimization
- **Brotli:** ON (better than gzip)
### Early Hints
**Path:** Speed → Optimization
- **Early Hints:** ON (preload critical resources)
### Rocket Loader
**Path:** Speed → Optimization
- **Rocket Loader:** OFF (can conflict with React hydration)
### Image Optimization
**Path:** Speed → Optimization → Image Resizing
- **Polish:** Lossless (or Lossy for smaller files)
- **Mirage:** ON (lazy loading for mobile)
- **Image Resizing:** Available on Pro+ plan
**Next.js Image Optimization:**
```typescript
// next.config.ts
const nextConfig = {
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
minimumCacheTTL: 2592000, // 30 days
},
};
```
## Security Settings
### SSL/TLS
- **Always Use HTTPS:** ON
- **HSTS:** Enable with max-age=31536000, includeSubDomains
### Firewall (WAF)
**Path:** Security → WAF
#### Managed Rules (Free Tier)
- **Cloudflare Managed Ruleset:** ON
- **OWASP Core Ruleset:** ON
#### Rate Limiting (Pro+ Plan)
```yaml
Rule: API Protection
If: Request URL contains /api/
Then: Rate limit 100 requests per minute per IP
```
#### Bot Fight Mode (Free)
**Path:** Security → Bots
- **Bot Fight Mode:** ON
- **Super Bot Fight Mode:** Pro+ plan
### Security Level
**Path:** Security → Settings
- **Security Level:** Medium (balance between security and UX)
### Challenge Passage
**Path:** Security → Settings
- **Challenge Passage:** 30 minutes
## Network Settings
### HTTP/2 & HTTP/3
**Path:** Network
- **HTTP/2:** ON (default)
- **HTTP/3 (QUIC):** ON (faster connections)
- **0-RTT Connection Resumption:** ON
### WebSockets
**Path:** Network
- **WebSockets:** ON (required for real-time features)
### gRPC
**Path:** Network
- **gRPC:** OFF (not needed for standard Next.js)
## Analytics & Monitoring
### Web Analytics
**Path:** Analytics & Logs → Web Analytics
- Enable Cloudflare Web Analytics (privacy-friendly, no cookie banner needed)
### Performance Monitoring
- **Core Web Vitals:** Track LCP, FID, CLS
- **Page Load Time:** Monitor at edge
### Real User Monitoring (RUM)
Add Cloudflare Zaraz or custom analytics:
```html
<!-- Cloudflare Web Analytics -->
<script defer src='https://static.cloudflareinsights.com/beacon.min.js'
data-cf-beacon='{"token": "YOUR_TOKEN"}'></script>
```
## Subdomain Configuration
Since you have multiple services, ensure proper routing:
### Traefik Labels (Dokploy Docker Compose)
```yaml
services:
app:
labels:
- "traefik.enable=true"
- "traefik.http.routers.mylder.rule=Host(`mylder.io`) || Host(`www.mylder.io`)"
- "traefik.http.routers.mylder.tls=true"
- "traefik.http.routers.mylder.tls.certresolver=letsencrypt"
```
### WWW Redirect (Cloudflare)
**Path:** Rules → Redirect Rules
```
If: Hostname equals www.mylder.io
Then: Redirect to https://mylder.io$1 (301 permanent)
```
## Testing Checklist
### DNS Propagation
```bash
dig mylder.io
nslookup mylder.io
```
### SSL Certificate
```bash
curl -I https://mylder.io
# Check for: HTTP/2 200, cf-cache-status header
```
### Cache Verification
```bash
curl -I https://mylder.io/_next/static/[hash]/[file].js
# Look for: cf-cache-status: HIT
```
### Performance
```bash
# Lighthouse
npx lighthouse https://mylder.io --view
# WebPageTest
# Visit https://www.webpagetest.org
```
## Troubleshooting
### 521 Error (Web Server Down)
- Check Traefik is running: `docker ps | grep traefik`
- Check Dokploy deployment status
### 522 Error (Connection Timed Out)
- Verify firewall allows Cloudflare IPs
- Check VPS security groups
### 525 Error (SSL Handshake Failed)
- Ensure SSL/TLS mode is "Full (strict)"
- Verify Traefik has valid Let's Encrypt certificate
### Cache Not Working
- Check Cache-Control headers in response
- Verify Page Rules are active
- Clear Cloudflare cache and test
### Mixed Content Warnings
- Enable "Automatic HTTPS Rewrites"
- Update hardcoded http:// URLs to https://
## Cost Optimization
### Free Plan Limits
- 100k requests/day (~3M/month)
- Unlimited bandwidth
- Basic DDoS protection
- Shared SSL certificate
- 3 Page Rules
### When to Upgrade to Pro ($20/month)
- Need more than 3 Page Rules
- Want Image Optimization (Polish, Mirage)
- Need custom SSL certificate
- Require advanced WAF rules
- Want priority support
### Enterprise Features (for future)
- Cloudflare Workers (serverless at edge)
- Load Balancing
- Argo Smart Routing
- Custom WAF rules
## Next Steps
1. **Immediate:** DNS + SSL/TLS setup
2. **Week 1:** Caching rules + performance testing
3. **Month 1:** Monitor analytics, tune cache rules
4. **Quarter 1:** Consider Workers for edge logic (see cloudflare-workers-roadmap.md)
## References
- [Cloudflare DNS Docs](https://developers.cloudflare.com/dns/)
- [Next.js Cloudflare Deployment](https://nextjs.org/docs/app/building-your-application/deploying)
- [Cloudflare Cache API](https://developers.cloudflare.com/cache/)