Every self-hosting site should eat its own cooking. This one runs on Hugo, a free theme, GitHub, and Cloudflare Pages. Monthly hosting cost: €0. Domain: ~€10/year. That’s it.

If you’re thinking about a blog or docs site, this stack is hard to beat.

The Stack

Component What Cost
Static site generator Hugo Free
Theme PaperMod Free
Source control GitHub Free
Hosting + CDN Cloudflare Pages Free
Analytics Cloudflare Web Analytics Free
Domain Cloudflare Registrar ~€10/year

No servers. No databases. No PHP. I write markdown, push to GitHub, and the site updates in about 30 seconds.

Why Static Over WordPress

WordPress needs hosting, a database, PHP, security updates, caching plugins, and constant attention. A static site is a folder of HTML files served from a CDN. There’s nothing to hack, nothing to patch, nothing to go down at 3am.

I’ve run WordPress sites before. The maintenance overhead is real, even for a simple blog. With Hugo, I spend time writing instead of updating plugins.

Why Hugo

Fast, easy, sort of standard nowadays. Builds in under 500ms, spits out plain HTML. You write markdown in your text editor, push to git, done.

Why PaperMod

It’s just a theme. I like it - dark mode by default, table of contents, code copy buttons. Blowfish, Congo, and Stack are also good. Pick one and move on, you can switch later.

Setting It Up

Install Hugo

You need the extended version (for SCSS support, which PaperMod uses).

# macOS
❯ brew install hugo

# Linux (Debian/Ubuntu) - grab the .deb from GitHub releases
# https://github.com/gohugoio/hugo/releases
❯ wget https://github.com/gohugoio/hugo/releases/download/v0.156.0/hugo_extended_0.156.0_linux-amd64.deb
❯ sudo dpkg -i hugo_extended_0.156.0_linux-amd64.deb

Check it works:

❯ hugo version
hugo v0.156.0+extended+withdeploy darwin/arm64 BuildDate=...

Create the Site

❯ hugo new site homelabcraft
❯ cd homelabcraft
❯ git init

Add PaperMod as a git submodule:

❯ git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

Configure hugo.toml

Here’s a trimmed version of what I actually use:

baseURL = "https://homelabcraft.com/"
languageCode = "en-us"
title = "Homelabcraft"
theme = "PaperMod"
paginate = 10

enableRobotsTXT = true
buildDrafts = false

[params]
  env = "production"
  description = "Practical self-hosting guides, honest comparisons, and homelab builds."
  defaultTheme = "dark"
  ShowReadingTime = true
  ShowCodeCopyButtons = true
  ShowToc = true
  TocOpen = false
  TocSide = "right"

[markup.highlight]
  codeFences = true
  style = "monokai"

[outputs]
  home = ["HTML", "RSS", "JSON"]

The env = "production" line enables Open Graph tags and other SEO bits that PaperMod hides in dev mode. Don’t forget it.

outputs includes JSON - that powers the built-in search page. Free search, no external service.

Content Structure

I use page bundles. Each post is a folder with its own index.md and images:

content/
  posts/
    how-i-built-this-site-for-zero-euros/
      index.md
    your-first-homelab-what-you-actually-need-2026/
      index.md

This keeps everything self-contained. If a post needs images, they sit next to the markdown that uses them.

Write Your First Post

❯ hugo new posts/how-i-built-this-site-for-zero-euros/index.md

Edit the frontmatter, write your content, preview locally:

❯ hugo server -D

The -D flag renders drafts. Open localhost:1313 and you’ll see it.

Deploying to Cloudflare Pages

Push to GitHub

Create a repo on GitHub, then:

❯ git add .
❯ git commit -m "Initial commit"
❯ git remote add origin https://github.com/yourusername/homelabcraft.git
❯ git push -u origin main

Connect Cloudflare Pages

  1. Go to Cloudflare Dashboard → Pages → Create a project
  2. Connect your GitHub account and select the repo
  3. Build settings:
    • Build command: hugo --minify
    • Build output directory: public
  4. Add an environment variable: HUGO_VERSION = 0.156.0

That last part is important. Cloudflare’s default Hugo version is ancient. Set it explicitly or your build will fail with cryptic errors.

Custom Domain

If your domain is already on Cloudflare (it should be - free DNS, free SSL), adding it to Pages is one click. Go to your Pages project → Custom domains → Add. Done. SSL is automatic.

The Deploy Flow

From here, every git push to main triggers a build. Push a branch and you get a preview URL. I use this to check posts before merging.

The full cycle: save file → commit → push → live in ~30 seconds. No FTP, no SSH, no deploy scripts.

What You Get for Free

Hugo and PaperMod handle a surprising amount of SEO without any setup:

  • Sitemap at /sitemap.xml - auto-generated
  • robots.txt - enableRobotsTXT = true in config
  • RSS feed at /index.xml
  • Open Graph + Twitter Cards - from your frontmatter
  • Canonical URLs - automatic

For analytics, I use Cloudflare Web Analytics. It’s free, doesn’t use cookies, and is GDPR-compliant by default. One line of JavaScript, added through the Cloudflare dashboard - no code changes needed.

If I outgrow it, I’ll self-host Umami on my homelab. But for now, Cloudflare’s analytics tells me what I need to know.

Performance Results

Static sites on a CDN are fast. No surprises there. But the numbers are still satisfying.

This site scores 100/100 on every Lighthouse category on most pages. There’s no JavaScript framework to download, no database queries to wait for, no render-blocking resources. It’s HTML and CSS served from the nearest Cloudflare edge node.

Build time for the whole site is under 500ms. That will stay fast even with hundreds of posts - Hugo was built for scale.

Compare that to a typical WordPress site where you’re fighting for a 70 on Performance and installing three plugins just to get caching right.

What I’d Do Differently

Content first, pretty later. There are zero images on this site right now. Cover images, OpenGraph cards, fancy diagrams - all that can wait. Write the posts first.

I’d set up a Makefile sooner. I now have shortcuts for creating new posts, running the dev server, and building. Small thing, saves time.

Page bundles from day one. I started with flat markdown files and moved to bundles later. Bundles are better - start there.

Get Started

Total time from zero to live site: about 2 hours. Most of that is picking a theme and writing your first post.

# The whole thing in 6 commands
❯ hugo new site homelabcraft
❯ cd homelabcraft
❯ git init
❯ git submodule add https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod
# edit hugo.toml, write a post
❯ hugo server -D

Push to GitHub, connect Cloudflare Pages, done. You now have a site that’s faster than 95% of the web and costs nothing to run.