For a while my projects lived on shared Hostinger plans. It worked until it didn't: noisy-neighbor CPU steal, limited control, and a growing list of things I couldn't run. So I consolidated everything onto a single OVH VPS and never looked back.

The stack

The whole thing is Docker + Traefik v3 + Let's Encrypt. Traefik handles ingress for every service via per-container labels and mints certificates automatically, so adding an app is just a compose file and a hostname.

On one box I now run a multi-app product suite, a full media stack, this blog, a metrics dashboard, push notifications, and the FlameNet services, each isolated in its own container, each routed by host.

On CPU steal, specifically

This is worth knowing how to measure, because it is invisible from inside your application and it makes you blame your own code. Steal time is the percentage of CPU cycles your virtual machine was ready to use and did not get, because the hypervisor gave them to somebody else on the same physical host. Run vmstat 1 and watch the st column, or look at %st in top. Anything consistently above a few percent means you are being throttled by a neighbour, not by your workload, and no amount of profiling your own containers will find it.

That number is also the honest argument for a dedicated or committed instance over a burstable shared one. You are not buying more cores, you are buying the ones you already pay for.

Lessons learned

  • Plain Traefik beats a heavier stack. I started with extra tunneling layers and ripped them out. Vanilla Traefik with Docker labels is simpler to reason about.
  • Check CPU steal before blaming your containers. Half my "performance problems" on the old host were the hypervisor, not me.
  • Harden early. A public box gets scanned within minutes. CrowdSec, a WAF in detection mode, and an egress firewall are worth the afternoon.
  • Size for memory, not cores. The thing that actually takes a single-box setup down is running out of RAM, at which point the kernel kills whatever process is largest rather than whatever process is guilty. Put a limit on every container and give yourself swap.
  • Certificates have rate limits and they are per registered domain. Let's Encrypt counts every subdomain of the same apex against one weekly budget, so a scripted redeploy that re-requests certs can lock you out of issuing new ones for a week.

One VPS, one docker compose, everything under version control. It's the most boring, and most reliable, my infrastructure has ever been.