Host a blog with minimal cost


Minimal cost

My previous attempts at blogging were hosting Ghost Docker container on DigitalOcean and later on Linode at a monthly cost of approx. $5 to $7.

This is my next attempt at hosting a blog with following goals:

  • Eliminate the monthly cost: By hosting on Cloudflare Pages with free plan.
  • Eliminate storage backup management: By using Github repository with static site generator.
  • Eliminate Let's Encrypt certificate renewals for HTTPS: By using Cloudflare Pages, so I never have to worry about expiration!

I still need to pay for the custom domain name annually, hence the title of this blog is not "Hosting a blog for free". One could avoid domain name cost by using the default "" provided by Cloudflare Pages.

How to do it

Because of many permutations of configuration options available, in the following I share the high level ideas.

Pick a site framework

Pick your favourite site framework. I picked Zola because of my newly found love of Rust.

Setup Cloudflare Pages

This is a three step process when using Custom Domain, unless you want to use default domain name then skip directly to step (3):

1. Get a Domain Name.

I had already purchased my domain on

2. "Add a Site" under Cloudflare Website.

Adding a site with domain name purchased outside of Cloudflare requires original domain registrar (Google Domain in my case) to be updated to use custom name servers of Cloudflare.


Custom Name Server on Google Domains

3. "Create a project" under Cloudflare Pages.

Here I connected my Github account and the repository where I host Zola git project. My build output directory configuration is "public" on both Zola and Cloudflare Pages. The "public" directory is added in .gitignore.

Create a project

Thats it! Once everything is configured, publishing new blog posts or updating existing ones is as simple as a Pull Request merge.

Cloudflare Pages also creates a PR comment once PR preview is ready on "", so you can verify changes before merging!

PR Preview

Automation using IaC

It would be nice to create all of these using a reusable IaC, but as of this day, there is an open issue to support Cloudflare Pages in terraform-provider-cloudflare. And pulumi-cloudflare depends on same Terraform provider too.