Skip to content

Self-host Headscale

updated Jul 2026prices checked · Jul 2026Install verified on Ubuntu 26.04 · Jul 2026 · how we test
We earn commissions when you shop through the links below. Full disclosure →

An open-source, self-hosted implementation of the Tailscale control server — run your own coordination plane for a private WireGuard mesh and keep using the official Tailscale clients, without depending on Tailscale's hosted service.

Key facts

LicenseBSD-3-Clause
StackGo
Min RAM256 MB
Official imageyes
Difficulty
Our recommendation

Pick Headscale when you already like the Tailscale clients and the only thing you refuse to rent is the coordination server: it is a BSD-3-Clause Go binary with SQLite by default that implements a single tailnet — MagicDNS, ACLs and grants, subnet routers and exit nodes, an embedded DERP relay and OIDC registration are all on the features list — and the README scopes it at "personal use, or a small open-source organisation". There is no built-in web interface; the admin surface is the `headscale` CLI, with community UIs listed in the docs. If you want a mesh product with its own dashboard and users, that is NetBird.

Follow the Headscale deploy guide →

What you need

  • Any VPS with at least 256 MB of RAM
  • A domain you control — most self-hosted setups need HTTPS in front of them
  • About an afternoon — budget time for troubleshooting
Where to host itaffiliate disclosure
Hetzner Cloudrun it on
From $23.59/mo · 2 vCPU / 4 GB / 80 GB · EU + US
Get Hetzner Cloud (opens in new tab)
Kamaterafree trial
From $4/mo · 1 vCPU / 1 GB / 20 GB · US + EU + Asia
Start free on Kamatera → (opens in new tab)
DigitalOceanalso works on
From $6/mo · 1 vCPU / 1 GB / 25 GB · US + EU + Asia
Deploy on DigitalOcean → (opens in new tab)

Paid link — we earn a commission if you shop through it.

Install

Run these commands on your server:

# Headscale — control server only (no web UI); needs a config.yaml + TLS on 443
mkdir -p ./headscale/config ./headscale/data && cd ./headscale
curl -fsSL -o config/config.yaml https://raw.githubusercontent.com/juanfont/headscale/main/config-example.yaml
# Required edits: set server_url to your https:// URL, and change
# listen_addr from 127.0.0.1:8080 to 0.0.0.0:8080 or the port won't publish.
docker run --name headscale -d -p 443:8080 \
  -v $(pwd)/config:/etc/headscale -v $(pwd)/data:/var/lib/headscale \
  headscale/headscale:stable serve

What you take on

Headscale is small and well documented, but its maintainers are unusually explicit about what they do and do not support:

non-negotiable"Please note that we do not support nor encourage the use of reverse proxies and container to run Headscale" (README). The FAQ adds that container images are built "for convenience" but Docker deployment is not officially supported, and the container page is marked community documentation "not verified by headscale developers". Our snippet runs it in Docker — expect community-level help, in the Discord docker-issues channel.
non-negotiableUpgrade one minor at a time. The FAQ's rule is "0.26.0 → 0.27.1 → 0.28.0" without skipping, always on the latest patch, and to read the changelog first: v0.29.3 (July 2026, the current release as of September 2026) needs Tailscale clients >= v1.80.0, and the unreleased 0.30 changelog already removes the gRPC API and changes CLI output shapes.
non-negotiableTLS on 443 is effectively mandatory: the requirements page says the Tailscale client "assumes HTTPS on port 443 in certain situations" and strongly recommends it for production. Our snippet publishes 443 to the container's plain-HTTP 8080, so either set tls_letsencrypt_hostname (needs port 80 free for HTTP-01, or TLS-ALPN-01 on 443) or tls_cert_path / tls_key_path — and the certificate must contain the full chain or the Android client rejects it.
non-negotiableIt is not built for churn. The FAQ says performance "is not part of the consideration": every network change recomputes a map for every node, so it "can likely handle 100s of devices (maybe more), if there is little to no change", while "many nodes with frequent changes will cause the resource usage to remain constantly high." Running Headscale on a machine that is itself in the tailnet is "not supported", and PostgreSQL is in "maintenance mode" — stay on SQLite.
non-negotiableThe 256 MB floor is our estimate; the requirements page publishes no RAM figure.

An alternative to

Head-to-head

More self-hosted tools

We use analytics cookies (Google Analytics, PostHog) to see which guides are useful. No ad networks, no cross-site tracking. See our privacy policy.