Skip to content

Commit 0ed05b2

Browse files
authored
Merge pull request #12 from karero/docs/cloudflare-deploy-conventions
docs(new-website): pages.dev vs workers.dev + DNS-cutover safety
2 parents c105b93 + d9f779f commit 0ed05b2

2 files changed

Lines changed: 85 additions & 0 deletions

File tree

skills/new-website/SKILL.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,15 @@ build finishes is it actually live at `<live-domain>` — confirm that separatel
347347
live at …"). On a **single-stage** site there is no preview: say plainly that the push **is
348348
going live now**.
349349

350+
**Which URL to quote.** Prefer the **memorable `pages.dev` alias** — the branch alias
351+
`main.<project>.pages.dev` (or the project alias `<project>.pages.dev`) — over the random
352+
per-deploy hash URL `<hash>.<project>.pages.dev`. The hash URL is ugly but **immutable**, so
353+
keep it as a **backup**: when an alias looks **stale** (cache/propagation lag, or it's still
354+
serving an older build), the hash URL pins the exact fresh deployment and confirms the new
355+
build is up. Whichever you quote, **open it and confirm it loads** rather than reporting it
356+
blind — and note it for the project. (A `pages.dev` URL is also the signal you deployed to
357+
**Pages**, not a Worker — see `references/CLOUDFLARE_FIRST_DEPLOY.md`.)
358+
350359
## Notes
351360

352361
- Do not rebuild what existing skills cover — GEO depth → `ai-seo`; technical-SEO/

skills/new-website/references/CLOUDFLARE_FIRST_DEPLOY.md

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,14 @@ npx wrangler pages deploy dist --project-name <project>
9292
# (Zone>DNS>Edit is only needed if you also script the DNS record itself.)
9393
```
9494

95+
> **`pages deploy`, not plain `deploy` — or you get a `workers.dev` URL.** These are static
96+
> **Pages** sites: every command above is `wrangler pages …` and the deploy must print a
97+
> **`<project>.pages.dev`** URL. A bare `wrangler deploy` (no `pages`) publishes a **Worker**
98+
> and hands back a `*.workers.dev` URL instead — a real mistake we've seen on an older kit
99+
> version. If you see `workers.dev`, stop: you deployed the wrong project type. Confirm it's
100+
> the accidental Worker (not a pre-existing one with a similar name), then delete it and
101+
> re-run `wrangler pages deploy`.
102+
95103
Ongoing deploys under (A): re-run `wrangler pages deploy dist --project-name <project>`
96104
(wrap it in `npm run ship` if you want one command — note the stock `ship.sh` targets the
97105
git-push model of (B), so adapting it for direct-upload is a follow-up, not assumed here).
@@ -114,3 +122,71 @@ If the owner won't mint a token and won't do the dashboard alone: drive the dash
114122
your runtime's browser automation (**Claude in Chrome** under Claude Code; the agent's own
115123
browser tool otherwise — see `search-console-setup`), or read them the clicks one by one.
116124
Both work; both eat time and patience — which is why **(A) is recommended for true newcomers**.
125+
126+
---
127+
128+
## Going live: moving an existing domain's DNS to Cloudflare — verify twice
129+
130+
When the site replaces a domain that already serves mail and a live site elsewhere (a
131+
rebuild migrating its DNS to Cloudflare), the cutover is the **single riskiest moment** — a
132+
wrong or wrongly-proxied record silently breaks email or the site right when it goes live.
133+
Treat it as a checklist *with* the owner, never a fire-and-forget edit:
134+
135+
1. **Import, then check every record twice.** When Cloudflare scans the existing zone it
136+
often misses records. Compare the imported set against the old DNS provider's export
137+
**entry by entry, twice** — A/AAAA, CNAME, **all MX**, and every TXT (SPF, DKIM, DMARC,
138+
verification tokens). A missing MX or SPF record = broken mail. The scan is least reliable
139+
on **CNAME, SRV, and CAA** records even when A/MX/TXT come through, so confirm those by
140+
hand:
141+
- **Microsoft 365 / Outlook:** verify `autodiscover` (CNAME → `autodiscover.outlook.com`),
142+
the DKIM selector CNAMEs (`selector1._domainkey`, `selector2._domainkey`), and the
143+
Teams/Skype SRV records (`_sip._tls`, `_sipfederationtls._tcp`). A missing `autodiscover`
144+
has been seen on a real migration (Cloudflare may have since improved this — **verify, don't
145+
assume**); without it Outlook mailbox auto-setup breaks.
146+
- **CAA** records — two failure modes: if existing CAA records are *dropped*, or if they
147+
are *restrictive and don't list Cloudflare's CA*, Cloudflare can't issue the TLS cert
148+
for the domain (including the Pages custom domain). If any CAA records exist, **confirm
149+
they permit Cloudflare's CAs before go-live.**
150+
- **Wildcard (`*`)** records and **subdomain NS delegations** — both commonly skipped.
151+
2. **Get a screenshot and double-check it.** Have the owner screenshot the final Cloudflare
152+
DNS table and pass it back so you can review it against the old zone before they flip the
153+
nameservers. A second pair of eyes catches the record that was dropped or mistyped.
154+
3. **Know which records must NOT be proxied (grey cloud, DNS-only).** Cloudflare's orange
155+
"proxy" cloud only makes sense for the **HTTP(S) hosts you actually serve through
156+
Cloudflare** (usually apex + `www` for this kit; proxy any other host only if it
157+
intentionally serves HTTP through Cloudflare). Everything else must stay **DNS-only**, or
158+
it breaks:
159+
- **MX records and the mail hostnames they point to** — proxying mail destroys delivery.
160+
- **SPF / DKIM / DMARC** and other **TXT** records (they aren't HTTP; proxy doesn't apply).
161+
- **CNAMEs that aren't your website** — the sneaky trap, because only A/AAAA/CNAME records
162+
*can* be proxied and onboarding often defaults the proxy **ON**: `autodiscover` /
163+
`autoconfig`, **DKIM selector CNAMEs**, domain-**verification** CNAMEs, and third-party
164+
service CNAMEs (email, helpdesk, status pages). A stray orange cloud on any of these
165+
breaks the service — leave them DNS-only.
166+
- Any record that must resolve to its **real origin IP** (e.g. a service expecting the
167+
true address, not Cloudflare's edge).
168+
Make sure the owner *understands* this distinction — don't just set it silently.
169+
4. **Disable DNSSEC at the registrar before touching nameservers.** Check whether DNSSEC is
170+
enabled at the old provider/registrar; if it is, **turn it off first** (or follow
171+
Cloudflare's DNSSEC migration path). Flipping nameservers while the old DS record is still
172+
live leaves a signature chain Cloudflare can't satisfy — resolvers then return
173+
`SERVFAIL` and the domain goes dark. Re-enable DNSSEC in Cloudflare afterwards if wanted.
174+
5. **Only after the passes agree and DNSSEC is handled**, change the nameservers / flip the
175+
apex. Then confirm the site loads on the live domain **and** send a test email both
176+
directions.
177+
178+
> **Pages: attach the custom domain in the project — a DNS record alone isn't enough.** For a
179+
> Pages site, just adding a CNAME/record that points at `<project>.pages.dev` does **not**
180+
> connect the domain; the domain must be added through the Pages **Custom domains** flow
181+
> (dashboard, or the REST API in §A) or visitors get a **522**. And once it's attached, don't
182+
> "test" by pointing the record away from Pages and back — Cloudflare can serve errors until
183+
> it reactivates; use a redirect/origin rule for any temporary routing instead.
184+
185+
> **Make rollback cheap — and don't tear the old setup down yet.** Lower the record TTLs at
186+
> the old provider ~24h *before* the move. After the flip, **keep the old zone, site, and mail
187+
> running through the propagation window** — resolvers may serve cached DNS for a while, so you
188+
> want an instant fall-back. Only retire the old setup once the new domain is confirmed
189+
> resolving and mail flows both directions.
190+
191+
> Drive these changes *with* the owner, not through blind screen control — same guardrail as
192+
> the bootstrap token steps above.

0 commit comments

Comments
 (0)