So I built this website. Not because I needed one, but because I wanted one. There’s a difference, and that difference is about three weekends of tinkering when I should have been doing literally anything else.

The Stack Nobody Asked For

I went with Hugo for the static site generation because, honestly, I’m tired of JavaScript frameworks. Sometimes you just want to write markdown and have it turn into a website without installing 47,000 dependencies. Hugo is fast, it’s simple, and most importantly, it gets out of my way.

The landing page is custom HTML and CSS because I wanted something that felt uniquely “me” without fighting against a theme’s opinions. Catppuccin Mocha for the color scheme because if you’re going to stare at your own website, it might as well be easy on the eyes.

Docker for deployment because containerizing things makes me feel like a real developer. Caddy as the web server because life’s too short to configure nginx SSL certificates manually.

The Obsidian Workflow

I write all my blog posts in Obsidian. Not in a code editor, not in some web interface. In my note-taking app where I already live half my digital life.

The Obsidian Git plugin does the heavy lifting. Every time I make changes to my vault (where the blog posts live), it auto-commits and pushes to my VPS. No manual git commands, no remembering to deploy, no “oh crap I forgot to publish that post” moments at 2 AM.

I write or edit a post in Obsidian, set draft: false in the front matter when it’s ready, and the Git plugin sees the change and commits it. It pushes to a bare repository on my VPS, which triggers a post-receive hook. Hugo rebuilds the site, the updated files land in the public directory, and Caddy serves them up immediately.

It’s just Unix doing Unix things.

The VPS Setup

On the server side, there’s a bare Git repository that receives the pushes. The post-receive hook triggers a rebuild script that builds a fresh Docker image with Hugo, runs Hugo to generate the static files, and extracts everything to the public directory. Caddy picks up the changes automatically.

No restart needed, no downtime, no ceremony. Just words going from my brain to the internet with minimal friction.

Why This Setup

The best writing workflow is the one you’ll actually use. For me, that’s Obsidian. I’m already there for notes, planning, and general brain-dumping. Having my blog posts in the same place means I’m way more likely to actually write them.

Plus, there’s something deeply satisfying about the whole thing being automated. I get to focus on writing (or in this case, writing about the system instead of using it), and the robots handle the deployment.

Would I recommend this setup to everyone? Probably not. It’s definitely overengineered for what amounts to a personal blog. But that’s kind of the point. Sometimes the journey is the destination, and the destination is a bunch of Docker containers talking to each other.

If I were being sensible (which, let’s be honest, isn’t my strong suit), I’d probably just use GitHub Pages and call it a day. But where’s the fun in that?

I wanted a place where I could write about code, art, and the weird intersection of the two. Something that felt like mine, built the way I wanted it built, with a workflow that doesn’t make me want to procrastinate.

Mission accomplished. Now I just need to actually use it.