Trying out Cloudflare Pages (with Deno + Lume)

When I started building this site, I decided I'd like to try hosting it on Cloudflare Pages. It gets a lot of love on Hacker News, and I appreciate Cloudflare's contributions to open source[1]. I already have a VPS on Hetzner[2], but I'm mostly using this for more sensitive self-hosted apps and I'd like to keep these apps separate from my public facing web property. Rather than spin up another VM for my website, I thought it would be a fun experiment to try out Cloudflare Pages. I don't need any of their advanced features for this little static site, so it's free with unlimited bandwidth, unlimited sites and deployment on their global CDN, which seemed like a good fit with no real risks.

Update: I've since moved from Cloudflare to a new VPS on Hetzner. I didn't like not having access to my HTTP logs. I found that I could pay $20 per month per domain to Cloudflare to get access to this. €4.55/mo on Hetzner was more appealing and, since I manage Linux servers for a living, wasn't a huge burden to maintain. Hetzner also alert me automatically if I go over 75% of my allotted 20TB of traffic, which I'd have to manually configure on Cloudflare if I'm serving large files with their R2 blob storage system. Moving to Hetzner also let me host my DNS with my registrar (my preferred approach).

It was a fun experiment and I learned a lot, but sometimes the old school approach is best.

👍🏻 The pros

  • It's free (with, as far as I can see, no chance of overages if your site is DDoS'd or you hit your 500 free builds per month).
  • The global CDN delivers great latency, anywhere.
  • It's fairly easy to get started.
  • The dashboard is nice and most options are easily discoverable without having to delve too deep into the docs.
  • If you do need to consult the docs, they're well written.

For most people, the pros will outweigh the cons.

👎🏻 The cons

There are a couple of downsides, the both of which might be deal breakers for a lot of people:

  • You need to use Cloudflare as your authoritative DNS server with a limit of 200 records per zone.
  • No access to raw HTTP access logs without enabling client-side JavaScript snippet.

Authoritative DNS

Having to use Cloudflare as your authoritative DNS is.. just OK. They don't charge per query, which is nice. But you're giving them a lot of data around site traffic for your entire domain (including subdomains that don't point to Cloudflare Pages, like your MX records). You're also trusting them as the gatekeeper to your entire online kingdom (as far as your domain is concerned).

My online presence is really mild, but if Cloudflare takes exception to something I publish via Cloudflare Pages (or my account is flagged as a false positive for a terms violation), they could technically suspend my account and disrupt delivery of my email. As insecure as email as, it's still the backdoor to virtually all our online lives (banking and finance, e-commerce, social media.. everything). My domain registrar (who I'd typically use as my authoritative DNS provider) could do the same, but it's less likely as I wouldn't be using them for content hosting so would be unlikely, for example, to be targeted with malicious DMCA claims. As a precaution, I'd suggest that if you use your domain for email, you should make sure that you have a secondary email address (on a non-CF-managed domain) setup as a backup with your domain registrar. Worst case scenario, you can move the NS records back to your registrar, breaking your Cloudflare Pages site but regaining access to your email by quickly setting up the correct MX records.

Additionally, a speed bump resulting from having to use Cloudflare for DNS is that setup can take a couple of hours depending on how long it takes your domain registrar to update your NS record.

Access logs

Cloudflare provides all sorts of high level analytics, showing stats like unique visitors and traffic by country. Here's an example of how they look in my account after my first 24 hours:

Screenshot of Cloudflare Analytics page showing overview with unique visitor graph and total requests

Screenshot of Cloudflare Analytics page showing map of request country, with Russia featuring heavily

These are sort of useful, but quite limited. In the examples above, after my Pages site had been up for around 24 hours, you can see 3.37k requests, the majority of which are coming from Russia. However, until now, this domain had only been used for email and (many months ago) for a private DNS over HTTPs server which had never been publicly linked anywhere. I suspect that every one of these requests (other than a handful of my test requests when setting up the site) are from bots, the domains gathered from compromised website email lists and certificate transparency logs.

Ordinarily, I'd have checked my server's access.log and looked at the URLs being requested and expected to see a bunch of automated attack attempts probing for broken WordPress installs and the like.

However, with Cloudflare Pages, I don't have access to an access.log or equivalent.

Cloudflare does have a feature called Web Analytics. This gives aggregate stats with request path (e.g. /some-page) and hostname (davebarker.xyz or www.davebarker.xyz). It doesn't look like it offers logs at the individual request level. The big downside to Web Analytics is that it requires you to add some client-side JavaScript to your site. While Cloudflare say that this is "privacy-first", you don't have any control over what this JavaScript does or collects. It's also useless for clients with JavaScript turned off or the analytics URL or domain blocked (which I do, at the DNS level). And it won't log anything from non-browser clients (like curl, or scripts).

If, for example, I host a really useful dataset in JSON or CSV format that I want people to grab and process with their own scripts, I have zero visibility over how popular that file is.

I've read about services like Logflare, where you set up a Cloudflare function that sends a log event every time a request is handled, which you can then analyse later. But services like that aren't free, require additional setup, depend on a third party, and export information (client IPs) which may be considered PII (Personally Identifiable Information) under some interpretations of the GDPR. All to reproduce what any web server gives you by default by turning on access logging.

I would much prefer to have access to basic HTTP access logs, even if I configure my web server to log only the client ASN (the network provider they're connecting from) and not the IP, for privacy purposes. Relying on client side JavaScript based logging is potentially bad for privacy, involves additional HTTP requests, and misses out all non-browser based traffic.

The $20 and $200 per month Cloudflare plans may offer more granular log access without the client side analytics, but at that point, for such a small personal site, I'd be better off just spinning up another Hetzner VPS for under €5 per month.

I don't need granular web logs, but this is enough to make me consider abandoning Cloudflare for my own web server.

🦕 Using Deno + Lume

Cloudflare supports a large number of web and static site frameworks out of the box, but doesn't have any preset templates for Lume. And they don't have Deno pre-installed in their build image.

Fortunately, it's trivial to configure a Lume deployment. The easiest way is to push your site to a private GitHub repo, enable the GitHub integration with Cloudflare (limiting it to that one repo) then set your build instruction to curl -fsSL https://deno.land/x/install/install.sh | sh && /opt/buildhome/.deno/bin/deno task build[3].

I did expect that I'd have to manually configure a GitHub webhook to make the site auto-deploy when I push my repo, but it appears that the integration does this behind the scenes. I couldn't find any documentation on exactly how it does this using the GitHub API, and there was no sign of a webhook against my repo, but it seems to just work.

🤔 Conclusion

So far, I'm ambivalent about Cloudflare Pages as a static web host. It's free, well documented and performant, but I'm a little uneasy about trusting them with my primary email DNS and I already miss having access to normal HTTP access logs without foisting client side analytics on my visitors. I'm undecided if I'll keep this site hosted on Cloudflare.

🐽 Domain registrar

As an aside, if you're looking for a decent domain registrar, I can heartily recommend Porkbun (and that's not an affiliate link, I just really like them as a provider!). Their pricing is decent, their dashboard well designed, and their marketing piggy illustrations quirky and cool.


  1. At work, I'm using cfssl for our mini CA to secure our network switch web interfaces. It's not perfect but it does what we need, and it'll be easier for the next sysadmin to manage than if I had cobbled something together with openssl or used the much more fully features step-ca. We're a tiny team and need to use minimal solutions where possible. ↩︎

  2. A rock solid host in Germany with really fair pricing (€4.55/mo for a 2 vCPU / 4GB RAM / 40GB NVMe SSD shared vCPU VPS). ↩︎

  3. Per the helpful Deno docs. ↩︎