Trying Cloudflare Pages

I’ve spent the majority of my day staring at my computer as I break and subsequently attempt to fix my website. It all started when I was able to gain access to get access to a new design framework — hopefully I’ll be able to show some things from that eventually. I figured it would be easier to work with this framework if I wasn’t using WordPress, though. So I decided I would move my site from WordPress to a static site generator like my all-time favorite Hugo.

To spoil any surprises, my experience with Cloudflare Pages didn’t go very well. It is still listed as a beta product, and of course Cloudflare as a whole is an extremely controversial topic in tech circles.

Note: This is not a guide for how to move from WordPress to a static site generator. I’ll touch on it a little bit, but the goal isn’t to be comprehensive.

Preamble

The first step was to attempt to convert my WordPress content into Markdown. I won’t go into the details since that could be a post in itself, but I used the wordpress-export-to-markdown utility. This worked fairly well, though it put each of the posts in their own named directory with an index.md file. I wrote a quick PowerShell script to take each Markdown file it found in the results and copy a version of it named after the directory to a shared folder with all of my Markdown content. I wrote another script to move all of the image files to the same location, and then yet another script to adjust the front matter of each Markdown file to be in the format that Hugo would expect. I’m guessing there are probably parameters on the wordpress-export-to-markdown utility to configure this but I failed to RTFM.

After I had all of the content into the format that I needed and organized appropriately, it was fairly trivial for me to make a new Hugo project. I linked this to a GitHub repository so that I could host my content somewhere after I felt good about how it looked. I had to make a few configuration changes, like specifying a permalink format in my config.toml file so that my URLs compiled by Hugo would match the existing ones in WordPress. This is important since it means any existing links to your site will continue to work. If you have any kind of existing SEO, this will help immensely.

[permalinks]
  posts = "/:title/"

At this point, I just had to figure out where to host the content. I’ve used GitHub Pages before along with Netlify and Firebase. Not wanting to push any of my existing free services too much, though, I decided to try out Cloudflare Pages. Like the other offerings I mentioned, you can use Cloudflare Pages to host your static content. You just point it to a Git repository, and it’ll host what you need from it.

Cloudflare Pages

Getting up and running with Cloudflare Pages was mostly easy. I first had to link it with my GitHub account so that I could prove that I owned the repository. You get the option to limit Cloudflare’s access to particular repos which I’d recommend using so that it can only see the repo you’re looking to host. After linking the repo, Cloudflare wanted to know what I was using to build the environment since it can do that for me. This means I can make changes to my template or to my Markdown-based content, and then Cloudflare can build the site for me rather than requiring me to build it locally and push that up to GitHub. Unfortunately, telling Cloudflare to build with Hugo didn’t work with an error that my theme didn’t support the version of Hugo Cloudflare was using. I unfortunately don’t recall the version of Hugo that was listed, but the Terminal theme requires version 0.74 as a minimum. Hugo’s current release at the time of this writing is 0.82. Version 0.74 released in July of 2020. So it’s not exactly bleeding edge.

This wasn’t a huge ordeal, though, because I could tell Cloudflare to not do anything with respect to the build. I instead just compiled the site myself as part of the commit and told Cloudflare to host what was already in the public folder that Hugo compiles to by default. I use the same thing with Netlify on another project which uses custom code to be built rather than something out of the box. This configuration worked fine, and I soon had my site up and running on Cloudflare’s pages.dev domain that they give you automatically.

Since everything looked good, I decided to take the plunge and switch my DNS so that https://unusually.pink would point to the Cloudflare Pages site rather than WordPress. This was a bit of a pain since I had to set Cloudflare as the nameservers for my domain before I could use it. Luckily Cloudflare imported all of my existing DNS records, which is important since I’ve set things like the MX records for Protonmail. Cloudflare imported everything, verified my DNS hosting was now with them, and my site was live. As I poked around the site more and more, I noticed a few issues here and there, mostly related to the conversion to Markdown and my attempt to make a static replacement for my WordPress About page. I pushed a few more commits with fixes, and everything seemed to process successfully.

At this point it was the middle of the afternoon, and I had been working on this since I woke up. I decided to take a (very) late lunch and do some cleaning. After those were done and my laptop battery was recharged, I sat back down to see if anything else was amiss. I noticed that the About page had broken CSS, which confused me since I fixed the link from my testing domain to my production domain with the last commit. Checking the deployment history of the site in Cloudflare, I saw that it was failing. The error message was extremely generic, letting me know the build environment was successfully initialized, but then the repository couldn’t be cloned:

Initializing build environment. This may take up to a few minutes to complete

Success: Finished initializing build environment

Cloning repository…

Failed: an internal error occurred

That’s doesn’t really tell me much about what is going wrong, and it’s all the more confusing that cloning the repo is what’s failing. I verified that the Cloudflare app did have access to that repo still, which it did. I then tried re-deploying quite a few times. When those all failed in the same manner, I made another mindless commit that I pushed up to origin so that the metadata would change, but deploying to Cloudflare persisted in failing the same way.

I next did what any decent IT professional would, which is searching the Internet to see if anyone else has experienced the same issue. It’s clear that Cloudflare Pages is a new product, though, because I could only find two support threads, neither of which has an answer. At this point I could have tried creating my own support thread and simply waiting, and that’s what I would have done if this was one of my random personal projects. Instead, the problem was with my main personal site, specifically the About page that I link to everywhere else on the Internet, from LinkedIn to Twitter to GitHub. I really didn’t want to leave that broken. I thought about just resetting my DNS and redirecting the site to Netlify, but I figured if I was going to have to wait for DNS regardless I would be extra safe and just roll everything back to WordPress. That’s why, if you’re reading the post right now, you’re seeing it on the same WordPress site you might be used to.

It’s Always DNS

Reverting my DNS wasn’t too painful thanks to Namecheap‘s setup. I just deleted the entire site from Cloudflare, which removes the site and the DNS from Cloudflare’s side. When I moved my nameservers to Cloudflare, I told Namecheap to point there. This doesn’t remove the DNS records I defined in Namecheap; it just makes them invisible to me since they don’t matter when someone else is acting as the nameserver. When I told Namecheap to flip back to itself for the nameservers on my domain, it also automatically restored the DNS records that were previously in place; I didn’t need to worry about recreating anything.

The only issue I saw after this was the standard DNS problem where cached entries hold on to the old DNS records. That’s normally okay, but noticed the DNS service I’ve been testing, Quad9, holding on to the old records for a long time. While after the TTL had expired I could query Google, OpenDNS, and even Cloudflare itself without any issues, Quad9 still would round robin between both the WordPress A records and the Cloudflare A records:

These queries were run probably a second apart. It’s however long it took me to hit the up arrow on my keyboard and execute the exact same command again.

This was a bit irritating, and even now several hours later I’m still seeing the same behavior from Quad9. I couldn’t even begin writing this post because my DNS would swap back to the Cloudflare site thus breaking the WordPress editor. After running many tests and realizing that it was only Quad9 clinging to the old records, I just changed the DNS servers on my home router. After that everything has been smooth sailing back on WordPress.

Wrap Up

So was all of today’s work actually a waste? Not necessarily. I still have the GitHub repo, and converting the content from WordPress to Markdown in a format that Hugo is happy with was the majority of the work. I could still see myself swapping to another static hosting option, though today’s activity also reminded me of how much I dislike doing any kind of frontend work.