Tooling

Self-Host Fleet (No Kubernetes)

A handful of boxes, Ansible / Kamal, and SSH. The 80% solution.

You've outgrown one VPS but Kubernetes is overkill. This is the sweet spot a huge number of profitable companies actually live in.

Components

  • Hardware: 3–10 VPSes from Hetzner / Hetzner Cloud / OVH / Vultr / DigitalOcean. Or bare metal at Hetzner Robot ($30–80/mo for huge boxes).
  • Orchestration: Kamal 2 (Basecamp's tool — Docker-based deploys to any SSH-able box). Or Ansible for fuller config management.
  • Reverse proxy: Caddy on each app server, or HAProxy / Nginx if you need fancier load balancing.
  • DB: Managed Postgres (Neon / Crunchy / RDS) or self-hosted with Patroni for HA.
  • Cache / queue: Redis / DragonflyDB on a dedicated box, or use Postgres for both (pg-boss).
  • Object storage: Cloudflare R2 (no egress) or Backblaze B2.
  • Network: Tailscale mesh; only 80/443 publicly exposed.
  • Observability: Prometheus + Grafana + Loki on its own VPS, agents on every host.
  • Backup: restic → R2 + DB-level WAL archiving.
  • Secrets: SOPS + age, or Doppler / Infisical (see web-dev secrets).
  • CI/CD: GitHub Actions → Kamal deploy / Ansible playbook.

What it's good at

  • Cost-effective at scale. A few Hetzner bare-metal boxes cost less than one similarly-sized AWS instance.
  • Predictable performance. Real CPUs, real disks, no noisy neighbors.
  • Total control. Custom kernels, weird storage, on-disk encryption — all yours.
  • Clear failure modes. When something breaks you can ssh in and look.

Where it strains

  • Ops time. Patching, log rotation, hardware failure, network blips — they're your problem.
  • HA storage. Real Postgres HA with Patroni is doable but non-trivial.
  • Compliance. SOC 2 evidence collection is harder without managed services.
  • Burst capacity. Hard to add and remove servers in minutes.

Tooling that makes this stack pleasant

Common topology

  • 1 reverse-proxy / load balancer box (Caddy or HAProxy).
  • 2–N app boxes (Kamal-deployed, identical).
  • 1 DB box (or managed Postgres).
  • 1 background-jobs box.
  • 1 monitoring / log box.

Multiply or split as needed. With a load balancer + 2 app boxes you can patch one while the other serves.

When to evolve

  • Cluster grows past ~15 boxes → consider Nomad or Kubernetes.
  • Multiple teams deploying to overlapping infra → IDP / k8s.
  • Need true autoscaling → managed cloud or k8s.

Pick this if…

  • 3–20 services, 2–10 engineers, modest growth.
  • You have at least one person who enjoys ops.
  • You'd like your AWS bill to look like a phone bill, not a mortgage.
  • Your data + compliance posture benefits from full control.

Skip if your team isn't comfortable in a terminal, or if your compliance team would prefer "the cloud handles that."

On this page