docs(deployment): add future scaling section for 50+ custom domains
Document two strategies for scaling beyond manual Caddyfile management: - Caddy on-demand TLS (simple, no Cloudflare protection) - Cloudflare for SaaS / Custom Hostnames (recommended, full protection) - Infrastructure scaling notes for 1,000+ sites Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -968,6 +968,53 @@ curl -I https://newplatform.lu/
|
||||
curl -I https://teststore.newplatform.lu/
|
||||
```
|
||||
|
||||
#### Future: Scaling Custom Domains Beyond 50
|
||||
|
||||
The manual Caddyfile approach (one block per custom domain + Cloudflare origin cert) works well up to ~50 custom store domains. Beyond that, managing Caddyfile blocks and origin certs becomes tedious. Two scaling strategies:
|
||||
|
||||
##### Option 1: Caddy On-Demand TLS (simple, no Cloudflare protection)
|
||||
|
||||
A single catch-all Caddy block replaces all custom domain blocks. Caddy auto-provisions Let's Encrypt certs on first request and validates domains against the database:
|
||||
|
||||
```caddy
|
||||
https:// {
|
||||
tls {
|
||||
on_demand
|
||||
ask http://localhost:8001/api/v1/internal/verify-domain
|
||||
}
|
||||
reverse_proxy localhost:8001
|
||||
}
|
||||
```
|
||||
|
||||
The `/verify-domain` endpoint checks the `store_domains` table — returns 200 (provision cert) or 404 (reject). Adding a new custom domain becomes a database insert only, no Caddy or Cloudflare changes needed.
|
||||
|
||||
**Limitation**: Custom domains point directly to the server (no Cloudflare proxy), so they lose DDoS protection, WAF, bot mitigation, and CDN caching. A DDoS attack on any custom domain impacts all sites on the server.
|
||||
|
||||
Let's Encrypt rate limits (50 certs/registered domain/week, 300 new orders/3 hours) are not an issue since each custom domain is unique. Caddy handles 5,000+ certs comfortably in memory (~50-100MB).
|
||||
|
||||
##### Option 2: Cloudflare for SaaS (recommended for production scale)
|
||||
|
||||
[Cloudflare for SaaS](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/) (Custom Hostnames) is how Shopify, Webflow, and major SaaS platforms handle custom domains at scale. Every custom domain gets full Cloudflare protection:
|
||||
|
||||
1. Configure a **fallback origin** in your Cloudflare account (e.g., `customers.omsflow.lu → 91.99.65.229`)
|
||||
2. Customer sets a CNAME: `wizamart.com → customers.omsflow.lu`
|
||||
3. Cloudflare proxies `wizamart.com` through your account — DDoS, WAF, bot protection, CDN all included
|
||||
4. SSL is automatic (no Let's Encrypt, no origin certs to manage)
|
||||
5. Adding a domain = database insert + one Cloudflare API call (automatable)
|
||||
|
||||
**Cost**: Available on Cloudflare Pro ($20/month) with per-hostname pricing (~$0.10/month each at volume). At 5,000 domains × $0.10 = ~$500/month for full Cloudflare protection on every customer domain.
|
||||
|
||||
**Hybrid approach**: Platform domains (`*.omsflow.lu`, `rewardflow.lu`, etc.) stay on the current Cloudflare setup with origin certs. Only customer custom domains use Cloudflare for SaaS.
|
||||
|
||||
##### Infrastructure scaling at 1,000+ sites
|
||||
|
||||
At this scale, the 4GB Hetzner VPS becomes the bottleneck before Caddy does. Plan for:
|
||||
|
||||
- Horizontal scaling: multiple app servers behind a load balancer
|
||||
- Dedicated PostgreSQL server
|
||||
- Dedicated Redis instance
|
||||
- CDN for static assets (Cloudflare, already in place)
|
||||
|
||||
## Step 15: Gitea Actions Runner
|
||||
|
||||
!!! warning "ARM64 architecture"
|
||||
|
||||
Reference in New Issue
Block a user