When running a Kubernetes cluster at home — such as on a Turing Pi board with ARM64 compute modules — efficiency and simplicity are top priorities. Running dynamic CMS platforms like WordPress or Ghost introduces databases, caching layers, and maintenance overhead.

By contrast, a static blog generated by Hugo requires almost no memory or CPU:

[Markdown] -> [Hugo build] -> [Nginx alpine] -> [Kubernetes Pod (~10MB RAM)]

The Deployment Architecture

1. Multi-Stage Container Build

The Dockerfile uses a two-stage build:

  • Build stage: Alpine Linux with Hugo installed compiles the markdown content into static files.
  • Runtime stage: A hardened nginx:alpine image copies the generated static assets and serves them with caching, compression, and security headers.

2. Declarative Kubernetes Manifests

The application is defined using pure Kubernetes manifests organized with Kustomize:

  • Deployment: Runs 2 replicas with non-root security contexts and minimal resource requests (10m CPU, 16Mi RAM).
  • Service: ClusterIP service routing traffic to port 80.
  • Ingress: Configured for abomb.dev with TLS termination managed via cert-manager.

3. GitOps with Argo CD

Argo CD continuously monitors this Git repository (or an Argo CD config repository) and ensures the cluster state matches what is committed. If anything drifts, Argo CD brings it back into compliance automatically.

Writing a new blog post is as simple as:

hugo new posts/my-new-article.md
# Write your content in markdown...
git add .
git commit -m "Add new post: my new article"
git push origin main

Everything else is fully automated.