Switching hosts without breaking my email

  • dns
  • deploy
  • hosting

I rebuilt this site as a static Astro project and moved it to a new host. Building and deploying it was the easy part: connect the repo, set one environment variable, push to main. The interesting work was pointing the real domain at it, because coltonpomeroy.com was still a live site on my old provider and, more importantly, my email runs through that same provider.

Here is what actually mattered.

The constraint: my email lives with my DNS

My domain, my DNS, and my email are all with the same provider. That last one shaped every decision. When you add a domain to a modern static host, the friendly, one-click path it offers is “change your nameservers to ours.” Do that and the new host becomes the authority for the entire zone. It also means every record your old provider was managing for you, including your MX records, stops existing unless you recreate it.

So the rule I followed: keep DNS where your email is, and change only the website records. I left the nameservers with my old provider and touched exactly two things:

  • the apex A record → the new host’s IP
  • the www A record → the same IP

The MX records and the SPF/DKIM TXT records never moved. Email kept flowing the whole time.

Gotcha: a hosted domain won’t point away

The first attempt to add the apex A record failed with “this modification conflicts with existing system DNS records.” Because the domain still had active web hosting with the old provider, that provider was auto-managing the apex record and would not let a custom one override it.

The fix was to switch the domain into a DNS-only mode. That sounds scarier than it is: it takes the old site offline but does not delete the files, does not cancel the plan, and explicitly leaves email and MX records intact. It is also reversible. Once the domain was DNS-only, the custom A records went in cleanly.

The part that looked like an outage

This is the bit worth remembering. DNS propagated fast, because my provider’s default TTL is five minutes. Within a few minutes, every resolver I checked returned the new host’s IP:

dig +short coltonpomeroy.com A @1.1.1.1
dig +short coltonpomeroy.com A @8.8.8.8

And yet the site was “down.” Loading https://coltonpomeroy.com failed at the TLS handshake. Here is why: DNS pointing at the new host is necessary but not sufficient. The host still has to issue the HTTPS certificate for the domain, and until it does, there is nothing listening with a valid cert on port 443. Plain HTTP was already returning 200; only HTTPS was failing.

curl -sI http://coltonpomeroy.com/    # 200, the host is serving
curl -sI https://coltonpomeroy.com/   # SSL error, cert not issued yet

Normally the certificate mints itself within a few minutes of DNS resolving. I did not want to sit in a broken state waiting, so I forced issuance from the host’s CLI. A few seconds later HTTPS answered 200, with a valid certificate, and the cutover was done.

What I would tell myself before starting

  1. Find out where your email is before you touch DNS. If it rides on the same zone, do not switch nameservers. Change the A records and leave everything else alone.
  2. Expect a short window where DNS is right but HTTPS is not. The domain can resolve to your new host and still fail to load, because the certificate has not been issued. Check plain HTTP to confirm the host is serving, then wait for or force the cert.
  3. Verify at every step with dig and curl. Resolution, then HTTP, then HTTPS, then the actual content. Each one rules out a different failure.

The whole migration, from a CMS-hosted site to a static one, cost a few minutes of HTTPS downtime and taught me exactly where the sharp edges are. Now every post, including this one, is a Markdown file that ships with a git push.