Host a blog with 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 "your-project.pages.dev" 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
Setup Cloudflare Pages
This is a three step process when using Custom Domain, unless you want to use default domain name my-project.pages.dev then skip directly to step (3):
1. Get a Domain Name.
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.
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.
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 "https://some-hash.my-project.pages.dev", so you can verify changes before merging!
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.