VPNSmith
self-host-vpnHOWTO

Headscale self-host: the sovereign Tailscale control plane (2026)

Headscale is the open-source Tailscale coordinator. Concrete guide: install on Contabo, Postgres backend, OIDC auth, ACLs, real costs and limits 2026.

By Eric Gerard · Founder · VPNSmith - Self-host VPN & GDPR VPS specialist10 min readPhoto via Unsplash

Affiliate disclosure - This post contains Contabo affiliate links. If you grab a VPS through them, we earn a commission at no extra cost to you. Every command and config below is documented from official sources and written to be reproducible on your own VPS.

If you've read our Tailscale vs WireGuard self-host comparison, you already know Headscale is the third path - the one that combines Tailscale-grade UX with WireGuard self-host sovereignty. The question is no longer "is it possible?" but "is it worth the setup time?". This guide answers that concretely, based on a standard Headscale deployment on a Contabo VPS.

Plan: what Headscale really is, when it makes sense (and when it doesn't), step-by-step install on Contabo with PostgreSQL and OIDC, ACL configuration, the production traps nobody warns you about, and 36-month costs vs Tailscale Premium. By the end, you'll be able to decide in 5 minutes whether to invest the 2-3 days a clean setup demands.

What Headscale actually is

Headscale is an open-source reimplementation of the Tailscale coordinator API, written in Go, maintained primarily by Juan Font and a tight contributor community. Source code: github.com/juanfont/headscale. License: BSD-3.

It's not a fork of Tailscale. It's a server that speaks the same protocol as the Tailscale SaaS coordinator - meaning the official Tailscale clients (iOS, Android, macOS, Windows, Linux) can be pointed at your Headscale instance and they'll behave normally. There's no patched client, no shady custom binary.

What Headscale handles:

  • Peer discovery and key distribution - exactly like the SaaS coordinator.
  • NAT traversal coordination - via DERP relays (you can use Tailscale's public DERP relays for free, or self-host your own).
  • Declarative ACLs - accepts the same JSON ACL format as Tailscale. Same syntax, same semantics.
  • MagicDNS - resolution of node.tailnet.example.com (or whatever domain you configure).
  • Subnet routes - to expose a VPC or LAN behind one node.
  • Exit nodes - to route all internet traffic through a chosen node.

What Headscale does NOT handle (the honest limits):

  • No official Premium features: no Tailscale SSH session recording, no native SSO console (you wire up OIDC yourself), no proprietary GUI admin (a separate headscale-ui project exists, third-party).
  • Mobile client management is more manual - auth keys must be generated CLI-side.
  • Tailscale Inc. support is non-existent - community support only, GitHub Discussions and Discord.

The promise is precise: most of Tailscale Premium's value, for the price of a small VPS, with a control plane you own.

When Headscale actually makes sense

Headscale isn't always the right answer. Here's the decision matrix to decide:

SituationRecommendation
Solo, 1-5 personal machinesTailscale Free, don't bother
Small team, 3-5 users, learning orientedRaw WireGuard self-host, simpler
Team 5-15, growth phase, no complianceTailscale Premium, time well spent
Team 10+, EU/sovereignty complianceHeadscale (ideal sweet spot)
50+ nodes B2B with SAML and audit logsTailscale Enterprise, the only one able
GDPR-critical infra, banking, public sectorHeadscale + audit hardening
Solo nerd, wants to learn full stackHeadscale as learning project

The two main reasons people deploy Headscale in production:

  1. Sovereignty / compliance: legal department or DSI bans uncontrolled SaaS dependency. Headscale checks the "European hosted, GDPR-compliant, no US transfer" box. It's the case in growing EU regulated B2B SaaS.
  2. Cash optimization at scale: at 15+ users, Tailscale Premium becomes 4-figure monthly invoices. A Contabo Cloud VPS 4 at €66/year + 2-3 days of sysadmin time costs less in cash; the 36-month table below shows the full calculation.

If neither of those drives your situation, stay on Tailscale Premium or raw WireGuard. The middle ground only makes sense if it's actually justified.

Architecture chosen for production

Here's the reference architecture this guide assumes:

[Tailscale client iOS/Android/Linux]
            │
            │ HTTPS (port 443)
            ▼
[Caddy reverse proxy] ──► [Headscale]
            │                    │
            │                    ▼
            │            [PostgreSQL 15]
            │
            └──► [Tailscale DERP relays - free public]

Components:

  • Contabo Cloud VPS 4 Nuremberg (4 vCPU, 8 GB RAM, 100 GB SSD, €5.50/month) - see our Contabo review 2026 and the step-by-step setup tutorial for getting the VPS ready.
  • Headscale 0.24 as the coordinator.
  • PostgreSQL 15 as backend (vs default SQLite, more robust as the node count grows).
  • Caddy 2 as reverse proxy with automatic Let's Encrypt TLS - Headscale needs HTTPS, the official clients require it.
  • OIDC via Authentik (also self-hosted, but Auth0 or Keycloak work too).
  • Tailscale public DERP relays for NAT traversal - free, no need to self-host DERP unless you have specific paranoia constraints.

Step-by-step install on Contabo

Source code in a terminal editor
Source code in a terminal editor

Setup time on a freshly provisioned VPS: about 90 minutes if you follow the steps without hesitation. We'll assume Debian 12 (the Contabo default).

1. System prep

apt update && apt upgrade -y
apt install -y postgresql postgresql-contrib caddy curl wget

2. Create the Headscale PostgreSQL database

sudo -u postgres psql <<EOF
CREATE USER headscale WITH PASSWORD 'PUT_A_STRONG_PASSWORD_HERE';
CREATE DATABASE headscale OWNER headscale;
GRANT ALL PRIVILEGES ON DATABASE headscale TO headscale;
EOF

3. Install Headscale

The official.deb package is the cleanest path. Latest release: github.com/juanfont/headscale/releases.

HS_VERSION="0.29.5"
wget https://github.com/juanfont/headscale/releases/download/v${HS_VERSION}/headscale_${HS_VERSION}_linux_amd64.deb
dpkg -i headscale_${HS_VERSION}_linux_amd64.deb

4. Headscale configuration

Values below are for Headscale 0.29 (October 2026). For the complete file matching your exact setup (Docker or .deb, Caddy, nginx or built-in TLS, SQLite as recommended upstream), use our Headscale config generator.

Edit /etc/headscale/config.yaml. The minimum required settings:

server_url: https://headscale.your-domain.com
listen_addr: 127.0.0.1:8080
metrics_listen_addr: 127.0.0.1:9090

database:
  type: postgres
  postgres:
    host: localhost
    port: 5432
    name: headscale
    user: headscale
    pass: PUT_A_STRONG_PASSWORD_HERE

derp:
  server:
    enabled: false
  urls:
    - https://controlplane.tailscale.com/derpmap/default

prefixes:
  v4: 100.64.0.0/10
  v6: fd7a:115c:a1e0::/48

dns:
  magic_dns: true
  base_domain: ts.your-domain.com

policy:
  mode: file
  path: /etc/headscale/acl.json

oidc:
  issuer: https://auth.your-domain.com/application/o/headscale/
  client_id: headscale
  client_secret: OIDC_SECRET_HERE
  scope: ["openid", "profile", "email"]

Critical points:

  • server_url must be HTTPS. The official Tailscale clients refuse to talk plain HTTP.
  • prefixes.v4: 100.64.0.0/10 is the CGNAT range Tailscale uses by default. Don't change unless you know what you're doing.
  • oidc: optional but strongly recommended in production. Without it you fall back to headscale users create and pre-shared keys.

5. Caddy as reverse proxy

/etc/caddy/Caddyfile:

headscale.your-domain.com {
    reverse_proxy 127.0.0.1:8080
}

Reload: systemctl reload caddy. Caddy automatically grabs the Let's Encrypt cert. Verify the chain is valid before going further - official Tailscale clients refuse self-signed.

6. Start Headscale

systemctl enable --now headscale
journalctl -u headscale -f

You should see startup logs, then "Listening on 127.0.0.1:8080".

7. Create a first user and a pre-auth key

headscale users create eric
headscale users list   # numeric ID of eric, e.g. 1
headscale preauthkeys create --user 1 --reusable --expiration 24h

The output gives a tskey-auth-xxxxxxxxxxxx key. Note it.

8. Connect a Tailscale client

On a Linux client with the official Tailscale client installed:

tailscale up \
  --login-server https://headscale.your-domain.com \
  --authkey tskey-auth-xxxxxxxxxxxx

The node appears in headscale nodes list. From there you can pull its 100.x.x.x IP and start using it.

For iOS/Android: install the official Tailscale app, settings → custom login server → enter your Headscale URL. Tap "Sign in", you'll be redirected to your OIDC provider.

Critical ACL configuration

ACLs are where Headscale shows it really is "Tailscale-compatible". The JSON file accepts the same syntax as Tailscale Premium ACLs.

Production example (5-user team with dev/staging segregation):

{
  "acls": [
    {
      "action": "accept",
      "src": ["group:admins"],
      "dst": ["*:*"]
    },
    {
      "action": "accept",
      "src": ["group:devs"],
      "dst": ["tag:dev:*", "tag:staging:22,80,443"]
    },
    {
      "action": "accept",
      "src": ["group:devs"],
      "dst": ["tag:prod:80,443"]
    }
  ],
  "groups": {
    "group:admins": ["eric@vpnsmith.com"],
    "group:devs": ["alice@vpnsmith.com", "bob@vpnsmith.com"]
  },
  "tagOwners": {
    "tag:dev": ["group:admins"],
    "tag:staging": ["group:admins"],
    "tag:prod": ["group:admins"]
  }
}

Reload after each edit: headscale acls reload. Headscale validates the JSON before applying, so a syntax error never breaks the prod mesh.

Production traps nobody mentions

Here are four traps to anticipate when operating Headscale:

1. PostgreSQL connection pool exhaustion. Headscale caps its PostgreSQL connections (database.postgres.max_open_conns and max_idle_conns). On a mesh with many nodes reconnecting often (think Wi-Fi roaming on phones), a pool that is too small becomes a bottleneck. Check the defaults in the example config of your version and raise them if the logs show connections waiting.

2. Tailscale public DERP relays may be far from some of your nodes. When traffic is relayed through a distant region, latency rises. Solution: self-host a DERP relay on a VPS in the region. Headscale handles it transparently - see the official DERP setup docs.

3. PostgreSQL backup is mandatory and underrated. Headscale stores everything in PostgreSQL: nodes, public keys, ACL state, OIDC mappings. Lose the DB, lose the entire mesh. Set up pg_dump daily + automated backup to an S3-compatible object store (e.g. Hetzner Object Storage, ~€1/month) and test your restore regularly.

4. Headscale binary upgrades are gentle but breaking changes happen between minor versions. Read the CHANGELOG before bumping from 0.23 to 0.24. The dev team is responsive on GitHub but Headscale is in active development - plan for them at each upgrade.

Real costs over 36 months - Headscale vs Tailscale Premium

The math at 10 users, 25 nodes, with cautious assumptions:

ItemHeadscale self-hostTailscale Premium
Direct cost 36m€198 (Contabo VPS) + €36 backup$6,480 (10 × $18 × 36m)
Initial setup2-3 days @ €400/d = €1,0001 hour, ~€50
Maintenance 36m~1.5h/month × 36m × €50 = €2,700~0.5h/month × 36m × €50 = €900
Backups + restore tests€200€0
Risk premium (outage)€500€0
Total 36m~€4,634~$7,430 ≈ €6,866

Headscale wins by ~€2,230 over 36 months at 10 users. Not enormous, but real - and the gap widens linearly with team size. At 20 users you're saving ~€8,000/3 years. At 50 users it's serious money.

If your time is worth more than €100/h, that gap shrinks fast. If it's worth less than €50/h (junior, side project, learning), Headscale wins easily.

Verdict - when to deploy Headscale in 2026

Deploy Headscale if:

  • You have a sovereignty / GDPR / no US transfer constraint
  • Your team is 10+ users with 12+ months horizon
  • You have an in-house sysadmin or sysadmin instinct
  • Tailscale Premium feels expensive but raw WireGuard feels too primitive

Stay on Tailscale Premium if:

  • Your time is worth more than €100/h
  • No specific compliance constraint
  • You'd rather spend that 2-3 days on your product

Stay on raw WireGuard if:

  • You're under 5 nodes, simple setup, learning mood
  • Hub-and-spoke fits all your use cases

Headscale is the most underrated answer in the self-hosted VPN ecosystem in 2026. It does most of Tailscale's job, on a Contabo VPS at €5.50/month, with full data sovereignty. The price is 2-3 days of setup and a sysadmin reflex.

Going further

Sources and references:


If you are still choosing between self-hostable control planes rather than between self-hosting and SaaS, NetBird versus Headscale compares the two directly - one keeps Tailscale's clients, the other ships its own.

Published 2026-06-05. Guide based on the official Headscale documentation, not on a production deployment of our own. Costs from May 2026 Contabo and Tailscale pricing - verify before deciding. Real performance and savings depend on team size and existing infrastructure.

Reminder: Headscale, Tailscale and VPN self-hosting are perfectly legal in the EU, US, Canada. VPNSmith publishes this content for educational purposes.

★ Nuremberg GDPR datacenter · ✓ Dedicated IPv4 included · 200 Mbit/s port

Self-host your VPN on your own VPS → ContaboFull root access · public IPv4 · pick your region→

Frequently asked questions

What is Headscale pricing?
There is no Headscale pricing, because Headscale is free open-source software - you download it and run it, and nobody invoices you per user or per device. What you actually pay for is the machine it runs on: a small VPS is enough for the control plane, since it coordinates the mesh and does not carry your traffic. So the honest comparison is not 'Headscale price vs Tailscale price' but 'the cost of a small server you administer' vs 'a per-user subscription someone else administers'. If your team is small enough to sit inside Tailscale's free tier, Headscale saves you nothing in money - it buys you control over the coordination server, which is a different reason to switch.
Is Headscale official Tailscale software?
No. Headscale is an independent open-source project (juanfont/headscale on GitHub) that reimplements the Tailscale control plane API. Tailscale Inc. does not officially endorse it but tolerates the existence of the project. The official Tailscale clients work with Headscale because both speak the same control plane protocol - but you carry the support burden.
Can I keep using the official Tailscale clients with Headscale?
Yes - that's the whole point. iOS, Android, macOS, Windows and Linux Tailscale clients can be pointed at your Headscale instance by overriding the login server URL. No fork, no custom build needed. You get the polished Tailscale UX with a coordinator you fully own.
How much does Headscale cost to run vs Tailscale Premium?
Direct cost: €66/year on a Contabo Cloud VPS 4 (€5.50/month). Tailscale Premium at 10 users runs about $2,160/year. Whether that pays back depends on what your setup and maintenance time is worth. Indirect cost: plan 2-3 days for initial setup, then 1-2 hours/month of maintenance.
Does Headscale support Tailscale ACLs and MagicDNS?
Yes for ACLs - Headscale loads the same declarative JSON ACL format as Tailscale. MagicDNS works since Headscale v0.23 with the DERP and DNS extensions enabled. SSH, file sharing (Taildrop), exit nodes, subnet routers - all of it functions. The notable gap is Tailscale SSH session recording, which remains a Premium-only feature on the SaaS side.