Building This Blog: Hugo + Forgejo CI + GitHub Pages
Building This Blog
When I decided to document my homelab adventures, I wanted something simple. No Kubernetes deployments. No container maintenance. Just write markdown and publish.
The Problem with Self-Hosting Everything
My homelab runs 90+ ArgoCD-managed applications across a 3-node Proxmox cluster. Adding another service means more maintenance, more updates, more things that can break at 2 AM.
For a simple blog? Overkill.
The Solution: Static Site + Free Hosting
I landed on this architecture:
graph LR
A[Forgejo Repo] -->|push to main| B[Forgejo CI]
B -->|hugo build| C[gh-pages branch]
C -->|mirror sync| D[GitHub]
D -->|GitHub Pages| E[hai.wxs.ro]
Source stays private in Forgejo. Public site lives on GitHub Pages with free SSL.
The Stack
| Component | Choice | Why |
|---|---|---|
| Static generator | Hugo | Fast builds, Go templating |
| Theme | Lotus Docs | Dark mode, search, diagrams |
| Source hosting | Forgejo | Self-hosted, private |
| CI/CD | Forgejo Actions | GitHub Actions compatible |
| Public hosting | GitHub Pages | Free, CDN-backed, zero maintenance |
How It Works
- Push markdown to
mainbranch in Forgejo - Forgejo CI builds the site with Hugo
- Built files pushed to
gh-pagesbranch - Forgejo mirror syncs to GitHub automatically
- GitHub Pages serves the content
The entire pipeline runs in under a minute.
Key Decisions
Why not Cloudflare Pages? GitHub Pages is simpler for this use case - just push to a branch.
Why Forgejo mirror? I already use Forgejo mirrors for backup. The gh-pages branch syncs automatically alongside the main branch.
Why Lotus Docs? Built-in FlexSearch, Mermaid diagrams, and dark mode without configuration.
What’s Next
This blog will document the homelab journey - infrastructure patterns, automation workflows, and lessons learned from running self-hosted services at home.