// the find
juanfont/headscale
An open source, self-hosted implementation of the Tailscale control server
Headscale is a self-hosted reimplementation of the Tailscale control plane, letting you run your own coordination server for WireGuard-based mesh networking without depending on Tailscale's SaaS. It's aimed at hobbyists and small teams who want full control over their tailnet. You still use official Tailscale clients; headscale just replaces the coordination server.
- Integration test suite is genuinely impressive - there's a whole `cmd/hi` test harness, Docker-based multi-client integration tests, and compatibility tests against actual Tailscale ACL test data, which catches protocol drift early
- Policy engine (v2) has extensive test coverage with golden files and compat tests pulled from Tailscale's own ACL test suite, giving high confidence in behavior parity for ACL evaluation
- Nix-based reproducible dev environment with a proper flake means contributors get identical tooling; the go.mod comments explaining the fragile modernc/sqlite/libc lockstep requirement show real operational awareness
- gRPC + REST gateway API with generated OpenAPI specs means there are multiple integration points, and the CLI is a proper first-class citizen rather than an afterthought
- Single-tailnet design is a hard architectural limit - explicitly intentional, but means you cannot use this for multi-tenant setups or organizations with separate network segments without running multiple instances
- The README explicitly discourages reverse proxy and container deployments, which is how most self-hosters want to run things; the actual workarounds exist in community docs but the official stance creates friction
- Tailscale protocol is not publicly documented, so headscale is perpetually chasing a moving target - capability version tracking (capver/) shows the maintenance burden, and new Tailscale client features can silently break or degrade until headscale catches up
- SQLite is the primary supported database in practice; PostgreSQL support exists but the test infrastructure (zombiezen.com/go/postgrestest) and community focus is clearly SQLite-first, so Postgres users may hit edge cases