Skip to main content
$ cd ../blog
-rw-r--r--  ricky  2026-02-12  8min  why-i-build-my-own-infra.md
Engineering

Why I Build My Own Infrastructure

Hetzner, Ubuntu, Caddy, systemd. No vendor lock-in. Here's why owning your stack matters more than ever.

Every product I run lives on machines I administer myself. Not a managed platform, not a serverless account with a dashboard — a Hetzner box running Ubuntu, with Caddy in front and systemd underneath. Marketing sites, a CRM, an analytics stack, a scheduler, a fleet of AI agents. One machine, one root shell, one place where everything is true.

People assume this is about saving money. It is partly about money. But the real reason is narrower and harder to buy: I want to be able to open the thing and look inside.

##What actually runs

The shape of it is deliberately boring. Ubuntu LTS. Caddy terminating TLS and reverse-proxying to local ports. Each app is a systemd unit with a port and a restart policy. Anything that wants to be a container is a container; everything else is just a process the machine knows how to keep alive.

// a service is this small
[Unit]
Description=Personal site (Next.js)
After=network.target

[Service]
WorkingDirectory=/srv/site/.next/standalone
ExecStart=/usr/bin/node server.js
Environment=PORT=3007
Restart=always

[Install]
WantedBy=multi-user.target

That is the whole deployment primitive. No build minutes, no proprietary config format, no waiting to find out which region is degraded. If a site is down, systemctl status tells me in one line, and journalctl tells me why in ten.

Caddy is the other half. It gets certificates on its own, renews them on its own, and the config reads like a sentence:

example.com {
  reverse_proxy localhost:3007
}

I have watched teams spend a week on TLS in a managed environment. This is four lines and it has never once woken me up.

##The part nobody advertises: it breaks, and that is the point

Owning your stack means owning your outages. I want to be specific here, because the honest version of this argument is more useful than the triumphant one.

A Next.js build in standalone mode does not copy your static assets into the standalone directory. It copies the server. It copies the manifests. It leaves .next/static and public/ behind. The site returns a clean HTTP 200 with the HTML intact and every stylesheet and script returning 404 — a page that is technically up and completely useless. Nothing alerts on that, because the status code is fine.

A runtime upgrade once required a Node version three patch releases newer than the one I had. The CLI refused to start. Another upgrade shipped a database migration that tried to fold a stale index into a live one, hit a conflict, threw, and took the service down in a restart loop — five failed starts and a dead unit.

None of those are arguments against self-hosting. They are arguments against pretending self-hosting is free. Every one of them was diagnosable in minutes because I could read the logs, inspect the filesystem, and see the actual error. The failure mode I am avoiding is not downtime. It is the support ticket — the one where you describe your symptom to someone who cannot see your system and wait.

Managed infrastructure does not remove failure. It removes your ability to look at it.

##Lock-in is a slow tax

The pitch for managed services is time. That is real, and early on it is often correct. What the pitch leaves out is that you are trading a capital cost for a permanent one — not just in the invoice, but in the shape of what you build.

  • -Your background jobs become their queue product.
  • -Your auth becomes their user model.
  • -Your data model absorbs assumptions you did not choose and cannot see.
  • -The migration you postponed gets more expensive every quarter.

Three years in, the question is no longer whether the pricing changed. It is whether you could leave at all. I would rather pay that cost up front, in a form I control, in tools that will still exist in ten years. Linux, nginx or Caddy, Postgres, and a process supervisor are not going to be sunset because a company got acquired.

##Self-hosting has gotten genuinely good

This argument used to require more conviction than it does now. The open-source replacements for the standard SaaS stack are no longer compromises. A self-hosted CRM, error tracking, social scheduling, workflow automation, a websocket server — all of it runs comfortably alongside everything else on hardware that costs less per month than a single seat of most of what it replaces.

The economics are not subtle. Per-seat pricing scales with your team; a server scales with your load, and modern hardware has far more headroom than most products will ever use. The cost curve that makes managed services attractive at three people is the same curve that makes them punishing at thirty.

##The Accra argument

I build between Columbus and Accra, and the case for owning your stack is sharper on the Ghana side. Card-first billing assumptions, currency exposure, region availability, latency to servers chosen for someone else's market — these are not edge cases there, they are Tuesday.

A dependency you cannot pay for reliably is not a dependency, it is a risk. Building on infrastructure you administer means the constraints you design around are your own — your users, your market, your latency — rather than the ones inherited from a platform that never modeled you as a customer.

##When you should not do this

I am not arguing everyone should run their own machines. Do not do this if nobody on your team wants to learn the operations side, because an unmaintained server is worse than any managed platform. Do not do this for anything where a bad night means regulatory consequences. And do not do this if it will consume the attention your actual product needs — infrastructure you own is a real, recurring commitment, and a half-owned stack is the worst of both.

The honest test is whether you want to understand your system. If you do, that curiosity compounds. If you do not, buy the managed thing and spend your attention where it matters.

##What you actually get

After years of running it this way, the compounding benefit is not cost and it is not uptime. It is that there is no layer of my stack I am afraid of. When something breaks, I do not file a ticket and refresh a status page. I ssh in and read the logs. When I want to add a service, I write a unit file and four lines of Caddy config. When someone tells me a thing is impossible on their platform, I check whether it is impossible or merely unsupported.

That is the whole argument. Owning your infrastructure is not about being clever or contrarian. It is about keeping the ability to look inside the machine that your business runs on — and being the person who can fix it.

← all posts