Somewhere between the invoice for the tenth seat-based SaaS tool and the third vendor breach notification of the year, most engineering teams have the conversation: should we just run this ourselves? Self-hosting internal services — source control, CI runners, secrets, dashboards, wikis — has become genuinely attractive again: mature open-source replacements exist for nearly everything, a modest server runs all of it, and data residency questions from customers and regulators get much easier when the answer is on our hardware, in this jurisdiction.
The failure mode is equally well known: a graveyard of half-maintained containers that one enthusiast set up, nobody patched, and everybody depends on. Self-hosting is not an install command; it is an operational contract. Signed deliberately, it is one of the highest-leverage moves an infrastructure team can make. Signed accidentally, it is a second job.
What is worth self-hosting — and what is not
- ▸Strong candidates: source control and CI (Forgejo or GitLab plus your own runners — the saving on CI minutes alone is often decisive), observability (Prometheus, Grafana, Loki), password and secrets management (Vaultwarden, OpenBao), internal wikis and file sync. Mature projects, simple state, tolerable failure modes.
- ▸Think twice: outbound email (deliverability is a full-time craft — host the mailbox if you must, never the sending reputation), anything customer-facing with an SLA tighter than your on-call rotation, and video conferencing at scale.
- ▸The deciding questions: What happens during four hours of downtime? Who restores it on a Saturday? Does the data inside make this server a target? If the answers are chaos, nobody, and yes, either buy the service or staff the contract properly.
The operational contract you are signing
Every self-hosted service carries the same five obligations whether or not you acknowledge them: patching on a cadence (the service and the host beneath it), backups proven by restoring, authentication that matches your company standard, monitoring by something outside the box itself, and documentation that lets a second person operate it. The trap is that each service seems to add only a little work — but the obligations multiply per service while your team does not. The countermeasure is standardization: one way to deploy, one front door, one backup pattern, one dashboard. Ten services run one way is a manageable estate; five services run five ways is five estates.
A reference architecture that stays small
The shape that has held up for us and for clients: one or two servers running containers via Compose or single-node k3s, defined entirely in a Git repository. In front of everything, one reverse proxy — Caddy or Traefik — terminating TLS with automatic certificates. Identity handled once: an OIDC provider such as Authentik or Keycloak, every application behind SSO, and services lacking native OIDC wrapped by a forward-auth proxy. Nothing exposed to the Internet except the proxy, with admin planes reachable only across a WireGuard overlay. Backups with restic or borgbackup to two destinations — one local, one off-site object store — encrypted client-side, following the 3-2-1 pattern. Finally, uptime monitoring from outside your own network, because the monitoring stack cannot report the death of its own host.
The runbook that keeps it boring
1. Everything in Git: compose files, proxy configuration, and a README per service with restore steps — the repository is the disaster recovery plan. 2. Patch on a schedule: a monthly window for image and host updates, with automatic security updates for the OS in between. 3. Restore quarterly: pick one service, rebuild it from backup on a clean host, and time it. An untested backup is a hope, not a control. 4. Audit the front door twice a year: every exposed port justified, every SSO integration listed, every stale account removed. 5. Name an owner and a deputy per service; a service with no second operator is scheduled for either training or decommissioning. 6. Review the estate annually: usage, cost versus the SaaS alternative, and whether each service still earns its operational keep.
Done this way, self-hosting returns three kinds of value. The visible one is cost — seat-based pricing for tooling a mid-size team uses daily routinely exceeds the amortized hardware and hours that replace it. The strategic one is control: your source code, secrets, and telemetry sit on hardware you answer for, in a jurisdiction you can name, which shortens security questionnaires and satisfies data-residency clauses that SaaS vendors negotiate around. The quiet one is capability: a team that operates its own estate — real backups, real SSO, rehearsed restores — carries that discipline into everything else it runs. The install command was never the point; the operational muscle is.
