It begins - blog hosting and design decisions

Everyone has their traditions.

As a developer, I start all my projects with a “Hello world”, that’s why the first post is so small. As a person, as jdgomez, all my projects continue with “It begins (don’t cry)”, so here is the second entry of the blog.

Context

As many people I bought a Raspberry Pi long ago, and I discovered how good it was at storing dust. Recently I remembered why I bought it (yes, to host my own blog), why I became a developer and I decided to push that project as a way to learn what AI can do for me.

Why the stack

“No. I mean, I’m not a shop boy. I was just working in a shop.” - Tristan Thorn 1

I started learning how to code with C++ and you can be sure I miss it so much. Right now I am focused on learning Go and Python. So my first decision was to code my own web server. It would be created in Go, and it would serve as a great exercise.

Luckily for me, one of my current goals is to learn more about AI, and I checked my plan with Claude Code and… that wheel was already invented.

Disclaimer: I really love to reinvent wheels (maybe a topic for another entry).

Hugo is a really fast and small framework for building websites. It’s written in Go, and can generate HTML from Markdown files. I like Markdown as a standard for documentation and clean files, I don’t want to bother with HTML or CSS.
I usually don’t like to use software in alpha versions and Hugo is in v0.161.1 right now. But this project is also about learning, and checking the Hugo GitHub page I discovered an active community with solid pipelines, so I am going to give it a try.

Nginx was a hard choice for me, because I have always been an ‘Apache boy’, but again, I am open to learn, so I asked Claude Code to do a deep research on performance. I usually over-engineer performance in my own code when the project constraints allow it, and I am a curious person, so why not check some data before choosing.

Here is the result:


Nginx vs Apache — Performance Benchmarks

RAM Usage

Scenario Nginx Apache (Event MPM)
Idle ~50–100 MB ~60 MB
100 concurrent connections ~15–20 MB ~40–60 MB
1,000 concurrent connections ~25–35 MB ~150–250 MB
10,000 concurrent connections ~50–100 MB ~2–5 GB

At idle, both servers are roughly equivalent. The gap grows dramatically under load: at 10,000 concurrent connections, Nginx uses 20–100x less RAM than Apache.

Why: Nginx stores ~2–5 KB per connection (just a file descriptor and minimal state). Apache allocates ~14–20 MB per process or thread.


CPU Usage

  • Nginx: ~120,000 req/s serving static files (modern x86 server)
  • Apache: ~70,000 req/s — 1.7x lower throughput
  • At 512 concurrent connections: Nginx 28,400 req/s vs Apache 15,200 req/s

Why: Apache generates thousands of context switches (one process or thread per request). Nginx uses a non-blocking event loop — a single worker handles 10,000+ simultaneous connections with no context switch overhead.


Disk Space

Nginx Apache
Binary ~1–6 MB (ARM: ~1.3 MB) ~10 MB
Full installation ~10–20 MB ~50–100 MB

Apache ships with a dynamic module directory (separate .so files), multiple configuration files, and per-directory .htaccess support. Nginx is more monolithic — modules compile into the binary, keeping the footprint small.


Raspberry Pi (ARM) — Real Hardware Numbers

Benchmark run directly on a Raspberry Pi:

  • Nginx: 1,067 req/s
  • Apache: 9 req/s

When Apache is configured with Event MPM and PHP-FPM (replacing mod_php), the gap narrows significantly (~108–109 req/s each). However, Nginx still wins on resource consumption across the board.


Conclusion: For serving static content (Hugo-generated sites), Nginx is the right choice on resource-constrained hardware like my Raspberry Pi.

For the domain I chose to drop all my current domains and trademarks, as they were intended for other purposes.

This is a personal blog, and I am a developer. It’s time to buy jdgomez.dev

I purchased it on Cloudflare because it’s cheap and can easily provide me with HTTPS and has an out-of-the-box tunnel to handle my dynamic address. My ISP offers a static IP option — that’s what I considered first — but at ~€144/year it makes no sense for a personal blog.

Steps taken

Usually I will post also the commands to achieve the result I am claiming, cause this is a blog about processes (mental and technical), not about goals.

Re-reading the article before publishing it, I realiced that the steps broke the flow and them don’t provide useful information (there are quite simple), but at the same time I don’t want to remove it, I am developer after all.

The solution is to hide them, check on it if you are interested.


Steps & commands
  1. Installed Hugo and Nginx via apt:
    • Hugo v0.131.0 extended (arm64)
    • Nginx 1.26.3
  2. Created Hugo site in /home/pi/blog/ with hugo new site blog
  3. Configured hugo.toml (baseURL, language, title)
  4. Created minimal layout in layouts/index.html (no external theme) with Hello World
  5. Built the site with hugo → output in /home/pi/blog/public/
  6. Configured Nginx to serve /home/pi/blog/public/ on port 80
  7. Disabled the default Nginx site
  8. Granted execute permissions on /home/pi so www-data can read the directory
  9. Verified access from local network → “Hello World”

Relevant file structure

/home/pi/blog/
├── hugo.toml          ← site configuration
├── layouts/
│   └── index.html     ← home layout (no external theme)
└── public/            ← Hugo build output (served by Nginx)
    └── index.html

/etc/nginx/sites-available/blog   ← Nginx config
/etc/nginx/sites-enabled/blog     ← active symlink

Final considerations

Although I am Spanish, the master language for the blog should be English, “the developer’s language”, and include my native language as a secondary option. I am currently learning German, but it’s too early for that. I will want to add it when the time comes to put it into practice, but I don’t want to do automatic translations. I am who I am, and this includes my language.

Finally, I always liked Uncle Bob’s blog, clear and simple.

So I chose to have a minimal custom theme, created from scratch by Claude Code, with clear instructions:

“I am a developer that hates cookies, my eyes prefer dark themes.”

This was its solution:

I couldn’t love it more.

The end

That’s all. That’s how all this begins. In the future I plan to add better time metrics on how much time it cost me to complete these little projects, including the article writing, but I didn’t properly measure it this time, so let’s consider it an improvement for next articles.

Hope you enjoyed this.

Thanks for reading.