Every FH client site has Cloudflare in front of it. Not because Cloudflare is fashionable — because the free plan plus a $20/month Pro plan does five things a cheap shared host can’t: a fast global CDN, DDoS protection, free SSL with automatic renewal, basic WAF rules, and DNS that doesn’t go down. The same configuration runs on every site in the FH client book. Here’s exactly what it looks like.
Why Cloudflare and not the deploy platform’s default
Vercel and Netlify both run their own CDN. They’re fine. But they’re behind a single vendor — if that vendor has an outage, your site is down. Cloudflare in front means a second layer that can serve cached content even when the origin is down. We use Cloudflare in front of Coolify-hosted sites (where it’s essential — Coolify VPSes are single-region) and in front of Vercel-hosted sites too (for the bot-management and Turnstile features Vercel doesn’t bundle).
Step 1: nameservers
Move DNS to Cloudflare. Log in, add the domain, Cloudflare scans the existing DNS, gives you two nameservers to point your registrar at. The change propagates in 1–24 hours depending on the previous DNS TTL. Until the propagation is complete, leave the old DNS as-is — Cloudflare’s scan will have copied your existing records.
Step 2: DNS records
For a Next.js site deployed to Coolify:
- A record: `@` → VPS IPv4, proxied (orange cloud).
- AAAA record: `@` → VPS IPv6, proxied. If your VPS doesn’t have IPv6, skip.
- CNAME: `www` → `@`, proxied.
- MX records: whatever your email provider gave you (Google Workspace, Resend, etc.), DNS-only (gray cloud).
- TXT: SPF, DKIM, DMARC for email. Don’t proxy.
- TXT: domain verification records for Google Search Console, Microsoft 365, etc.
Proxy through Cloudflare (the orange cloud) means traffic to that record goes through Cloudflare’s network — CDN, WAF, bot management all apply. DNS-only (the gray cloud) means Cloudflare just returns the record without proxying. Always proxy your A/AAAA/CNAME for HTTP traffic. Never proxy MX or domain-verification records.
Step 3: SSL/TLS mode
Set to Full (Strict). This means Cloudflare connects to your origin over HTTPS, validates the origin’s certificate, and serves HTTPS to the visitor. The alternatives — Flexible, Full (non-strict), Off — are all worse in specific ways. Flexible serves cached HTTP from the origin over HTTPS to the user, which causes mixed-content bugs. Full (non-strict) accepts self-signed origin certs, which kills the trust chain.
For Coolify-hosted sites, install a Let’s Encrypt cert on the origin (Coolify’s built-in Caddy or Traefik does this) so Full (Strict) works. For Vercel-hosted sites, Vercel’s origin cert is valid and trusted by Cloudflare automatically.
Step 4: Always Use HTTPS + HSTS
Cloudflare’s “Always Use HTTPS” toggle redirects every HTTP request to HTTPS at the edge. Enable it. Then enable HSTS with at least a 6-month max-age and `includeSubDomains`. After a month of stability, increase to 12 months and add `preload`, then submit to the HSTS preload list.
Step 5: caching configuration
Cloudflare’s default cache rules cache static assets aggressively (images, CSS, JS) and pass HTML through to your origin. For a Next.js site with static HTML pages, this is fine — your origin (Coolify or Vercel) serves the HTML quickly enough that caching at Cloudflare provides marginal benefit.
If you want HTML cached at the edge too, use a Cache Rule that matches `request.uri.path matches "^/"`, sets cache eligibility to `Eligible for cache`, and sets edge TTL to whatever staleness you tolerate (we use 1 hour for static marketing pages). The origin still serves on cache misses.
Step 6: Brotli and HTTP/3
Both should be enabled (they are by default on Pro). Brotli compresses HTML/CSS/JS better than gzip. HTTP/3 is faster on lossy connections. Neither has a meaningful downside.
Step 7: page rules for redirects
Anything you’d use a Next.js `redirects()` config for, you can do faster at Cloudflare’s edge. Common ones:
- Force www to apex: `www.example.com/*` → `https://example.com/$1`, 301.
- Legacy URL redirects: `/old-path` → `/new-path`, 301.
- Force HTTPS on a specific subdomain: `http://api.example.com/*` → `https://api.example.com/$1`, 301.
Edge redirects are sub-10ms. Application-level redirects through your Next app are 200ms+. For static redirect rules, always do them at Cloudflare.
Step 8: WAF rules
Cloudflare’s managed ruleset blocks the OWASP top 10 by default. On the free tier you get a basic ruleset; on Pro you get the more aggressive managed rules. We use Pro for any site that takes user input (a contact form is enough — bots find them quickly).
We add a few custom rules: rate-limit POST requests to `/api/*` and `/*/contact` to 10/minute per IP, challenge any request claiming to be from a known bot user agent that wasn’t allowlisted, block requests with no User-Agent header. Together these stop 90% of low-effort attacks.
Step 9: bot management
Cloudflare Pro includes basic bot management. The bot score is exposed as a request header, and you can write rules that challenge or block requests with low scores. For most SMB sites the default settings are fine — pair them with Turnstile on forms and you’re covered.
Step 10: monitoring
Cloudflare’s dashboard surfaces real-time traffic, threat events, cache hit ratio, bandwidth usage. We check it weekly across the client book. The two metrics that matter most: cache hit ratio (should be above 80% on static assets, 40%+ on HTML if you’ve enabled HTML caching) and threat events (zero is fine; a sudden spike is a signal).
When to add Cloudflare Workers
Not by default. Workers add complexity, and most of the things people reach for Workers for are better done in Next.js middleware or server actions. We add Workers when (1) we need behavior at the edge that has to happen before the Next app runs, like an A/B test variant selection that must persist across CDN cache layers; or (2) we need to manipulate response bodies at the edge for a specific route. Every other use case stays in the Next app.
Sites we DON’T put Cloudflare in front of
If a client is on Squarespace or another all-in-one builder where the platform handles SSL, CDN, and DDoS protection, adding Cloudflare in front creates more complexity than it solves. We respect the platform’s opinions on those sites and only use Cloudflare for DNS (DNS-only records, no proxy).
How this lands across FH client work
Every site we ship — BHR, james-marina, CabCarpentry, the Tivey site, fh-site itself — is behind Cloudflare with this exact configuration. Setup takes one afternoon. Maintenance is ten minutes a quarter checking the dashboard. Incidents prevented: every credential-stuffing attempt, every DDoS, every bot-scraping wave. If your site is hosted bare-metal or directly off a CMS without a CDN in front, book a consultation — adding Cloudflare is a free-to-cheap win every time.