Personal technical blog. Hugo static site, served by nginx, deployed to the existing EKS cluster, fronted by the same shared ALB as fabiorollin.com and contacts.fabiorollin.com.
Palette and typography matched to the main portfolio landing page.
Requires Hugo extended (v0.139+) installed locally.
# Install Hugo on Windows via winget
winget install Hugo.Hugo.Extended
# Live preview at http://localhost:1313
hugo server -D-D includes drafts. Drop it for production preview.
hugo new posts/my-new-post.mdEdit the front matter and content. Set draft: false when ready to publish.
hugo --minify --gcOutput goes to ./public. Don't commit it — built fresh in Docker.
1. Create the ECR repository:
aws ecr create-repository --repository-name blog --region us-east-12. Add the DNS record. In Route 53, create an A ALIAS record for blog.fabiorollin.com pointing at the same ALB used by the rest of fabiorollin.com. The wildcard ACM cert (*.fabiorollin.com) already covers it.
# Get the ALB DNS name
kubectl get ingress -A -o json | ConvertFrom-Json | `
Select-Object -ExpandProperty items | `
Where-Object { $_.metadata.namespace -eq "web-demo" } | `
Select-Object -ExpandProperty statusUse that hostname as the ALIAS target in Route 53.
$ECR = "807291695385.dkr.ecr.us-east-1.amazonaws.com/blog"
$TAG = (Get-Date -Format "yyyyMMdd-HHmm")
# Build
docker build -t blog:latest .
# Auth + push
aws ecr get-login-password --region us-east-1 | `
docker login --username AWS --password-stdin "807291695385.dkr.ecr.us-east-1.amazonaws.com"
docker tag blog:latest "${ECR}:${TAG}"
docker tag blog:latest "${ECR}:latest"
docker push "${ECR}:${TAG}"
docker push "${ECR}:latest"
# Apply manifests (first deploy only)
kubectl apply -f k8s/blog.yaml
# Subsequent deploys: just bump the image
kubectl set image deploy/blog "blog=${ECR}:${TAG}" -n blog
kubectl rollout status deploy/blog -n blogHard-refresh https://blog.fabiorollin.com after rollout.
- 1 pod, 25m CPU / 32Mi memory request — fits inside existing EKS Auto Mode capacity, no new node
- Shared ALB (no new ELB charge — the
alb.ingress.kubernetes.io/group.name: fabiorollin-sharedannotation joins the existing ALB) - Static files served by nginx — no DB, no API
- ECR: ~$0.10/month for the image storage
Net: ~$0.20/month added to the AWS bill on top of what you're already paying for the cluster.
blog/
├── hugo.toml # Hugo configuration
├── content/
│ ├── _index.md # Homepage description
│ └── posts/ # Blog posts (Markdown + front matter)
├── layouts/ # Inline custom theme
│ ├── _default/
│ │ ├── baseof.html # Outer HTML shell
│ │ ├── single.html # Individual post template
│ │ └── list.html # Tag/category list templates
│ ├── index.html # Homepage post-list layout
│ └── partials/
│ ├── header.html # Sticky nav with brand + links
│ └── footer.html # Site footer
├── assets/css/
│ └── main.css # Single CSS file, palette matches fabiorollin.com
├── static/
│ └── favicon.svg # Tiny SVG favicon (FR monogram)
├── Dockerfile # Multi-stage: hugomods/hugo → nginx:alpine
├── nginx.conf # gzip, cache headers, security headers, SPA fallback
├── k8s/blog.yaml # Namespace + Deployment + Service + Ingress
└── README.md # This file
Custom inline theme. ~200 lines of HTML across layouts/ plus ~250 lines of CSS in assets/css/main.css. Easier to modify than a community theme with its own configuration system, and matches the landing-page palette out of the box.
If you outgrow it: replace layouts/ with a Hugo theme submodule (e.g., themes/PaperMod) and add theme = "PaperMod" to hugo.toml. The content and config carry over unchanged.
hugo new posts/<slug>.md- Set
title,description,tags,draft: false - Write the post in Markdown
hugo server -Dto preview athttp://localhost:1313git add . && git commit -m "post: <title>"(if you've got a git remote set up)- Run the per-deploy commands above
- Hard-refresh the live URL
Repeat as you publish.