Switching hosts without breaking my email
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
Arecord → the new host’s IP - the
wwwArecord → 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
- Find out where your email is before you touch DNS. If it rides on the same zone,
do not switch nameservers. Change the
Arecords and leave everything else alone. - 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.
- Verify at every step with
digandcurl. 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.