Maksym Prokopov personal blog
Idea is a something worth sharing

Hosting for Static Assets

05.04.2025

I lived on GitHub Pages for static hosting for a long time. For example, this blog been hosted as https://mprokopov.github.io for years, just with the custom domain https://prokopov.me

But last week I finally moved everything to CloudFlare Pages and quite happy about it!

The major driver for the change was a hassle of management github-pages. It’s either your have to keep everything in a separate branch, with the name like github-pages, or have to use completly different repository. I chose the latter, and for a long time kept using two repositories, one with Hugo sources, second with rendered HTML. It was a bit painful to manage two git repositories in the same working tree, hugo build renders the website to the public folder. In addition, the repository with HTML should be public.

Options for free or almost free static hosting

AWS S3

Another option for static hosting is AWS S3, but the problem, it’s very inefficient without having AWS CloudFront in front of S3, slow and costly. Adding AWS CloudFront adds to burden of infra management.

Google Firebase Hosting

One more option is a Google Firebase Hosting, that includes free hosting. It’s nice, but the downside, setting up authentication for gcloud is a hassle.

CloudFlare Pages

Last week I decided to check what’s going on with CloudFlare, and it turns out they have a very generous offer on CloudFront Pages. Setting up GitHub Actions was as easy as adding this snippet

    - name: Deploy to CloudFlare
      uses: cloudflare/wrangler-action@v3
      with:
        apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
        accountId: <account-id>
        command: pages deploy . --project-name=<project-name>
        workingDirectory: public

And it works like a charm!

As the follow-up, Cloudflare Pages support even better integration with GitHub via GitHub App and allows to have a dedicated previews, which is for content with approval workflows is a very nice addition!

Terraform with CloudFlare

Nice part about infrastructure as a code, now it’s repeatable! I can add a new hosting just by adding a new terragrunt module in no time.

Example of terraform module. Also, DNS entry should be changed to CloudFlare provided CNAME for the website.

resource "cloudflare_pages_project" "main" {
  name = var.project_name
  account_id = var.account_id
  production_branch = var.production_branch
}

resource "cloudflare_pages_domain" "main" {
  account_id = var.account_id
  project_name = var.project_name
  domain = var.domain

  depends_on = [
    cloudflare_pages_project.main
  ]
}

Summary

It was a good decision!