Deployment guide

Self-Host Headscale on a VPS: Your Own Tailscale Control Server

Deploy on a VPS Cloud →

Security & Monitoring5 min read

Self-Host Headscale on a VPS: Your Own Tailscale Control Server

Tailscale's free tier caps you at 3 users and stores your network map in the cloud. Headscale (BSD-3-Clause, ~41k stars) is a drop-in open-source replacement for the Tailscale coordination server — deploy it on your VPS and keep using the official Tailscale clients on every device. Your team connects with zero-trust WireGuard tunnels, magic DNS, and ACL-based access control, all self-hosted and unlimited.

Why self-host the control server

Tailscale is exceptional software — WireGuard performance, cross-platform clients, magic DNS that just works. The control plane (the coordination server that distributes keys and ACLs) is what runs in Tailscale's cloud. Headscale reimplements that coordination server in open-source Go so you can run it on your own infrastructure.

Beyond the 3-user free tier limit, the main reason to self-host is data residency: the control plane knows which machines are on your network, their IPs, and your ACL policies. Running Headscale means that information stays on your VPS — not in someone else's cloud.

What self-hosted Headscale gives you

  • Unlimited users and devices: no 3-user cap, no per-seat pricing — your mesh scales with your team.
  • Official Tailscale clients everywhere: Linux, macOS, Windows, iOS, Android — no custom fork or alternative client required.
  • WireGuard peer-to-peer tunnels: Headscale only handles key exchange and ACL distribution; all actual traffic is direct WireGuard between peers.
  • Magic DNS: resolve every node in your mesh by hostname (machine.headnet.local) without modifying public DNS.
  • HuJSON access control lists: the same ACL policy format as Tailscale — define which users and devices can reach which services.
  • DERP relay support: use Tailscale's public DERP map for NAT traversal, or deploy your own private relay.
  • REST API and headscale CLI: create namespaces, issue pre-auth keys, and manage peers programmatically.
  • Under 50 MB RAM at idle — runs comfortably on a 1 GB VPS alongside other workloads.

Requirements

A VPS with at least 1 vCPU and 512 MB RAM running Ubuntu 22.04, with Docker and Docker Compose v2 installed. A domain name pointing to the VPS is required — Tailscale clients connect to the control server by URL, and HTTPS (via a reverse proxy like Caddy or Nginx with Let's Encrypt) is strongly recommended. Port 8080 must be reachable from the internet (or just from your devices if you prefer an internal-only control plane).

Deploy Headscale with Docker Compose

01

Write the Compose file

Create /opt/headscale/compose.yaml. The stack is a single service: headscale/headscale:0.29.2. Headscale stores everything — keys, database, node records — in named Docker volumes mounted at /etc/headscale (config) and /var/lib/headscale (data). No external database or cache service is required; SQLite is built in.

02

Generate the configuration

Headscale reads its configuration from /etc/headscale/config.yaml. The minimum required field is server_url — the HTTPS URL your Tailscale clients will connect to (e.g. https://vpn.yourdomain.com). Set listen_addr: 0.0.0.0:8080 and database.type: sqlite3 with a path under /var/lib/headscale. The private key paths (private_key_path, noise.private_key_path) will be auto-generated by Headscale on first start if they do not exist. On ServOrbit, the provisioning job writes config.yaml from your domain automatically.

03

Start the container and verify

Run docker compose up -d. Headscale will auto-generate its WireGuard private key and noise key, then start listening on port 8080. Check the health endpoint: curl -s http://localhost:8080/health should return {"status":"pass"}. The headscale CLI is available inside the container: docker exec headscale headscale version to confirm the running version.

04

Create a user and generate an auth key

Tailscale organizes devices into 'users' (formerly namespaces). Create one: docker exec headscale headscale users create myteam. Then generate a pre-authentication key to register devices: docker exec headscale headscale preauthkeys create --user myteam --reusable --expiration 24h. Copy the printed key — you will use it when registering each device.

05

Register a device

On any device with the official Tailscale client installed, point it at your Headscale instance: tailscale up --login-server https://vpn.yourdomain.com --authkey <your-preauth-key>. The device will appear in your Headscale node list within seconds: docker exec headscale headscale nodes list. Repeat for every device. Once registered, devices can reach each other by their mesh IP (100.x.x.x) or by magic DNS hostname.

06

Define access control policies

Create /etc/headscale/acls.hujson and reference it in config.yaml via acls_path. Headscale uses the same HuJSON ACL format as Tailscale Cloud: define groups of users, tag devices as servers or workstations, and write rules specifying which groups can reach which ports. A minimal policy allows all users to reach all nodes; tighten it by restricting access to sensitive services (databases, admin panels) to specific user groups.

07

Logging in for the first time

Headscale has no web interface and no account: it is the control server of your private network, driven from the command line. Over SSH: docker exec -it headscale headscale users create monuser, then headscale preauthkeys create --user monuser --reusable --expiration 24h, and connect your machines with tailscale up --login-server https://<your-domain> --authkey <key>.

Pair Headscale with Authelia for MFA-protected network access

Headscale handles network-layer access control (which IPs can talk to which peers), but it does not enforce application-layer authentication. Pair it with Authelia running on the same VPS: route your internal services (accessible only via the mesh) through Authelia's forward-auth layer. Users must complete MFA to access services even once they are on the mesh — defense in depth for sensitive workloads.

Headscale vs Tailscale Cloud

Tailscale Cloud remains the easier path for small teams: no server to maintain, automatic upgrades, integrated billing. Headscale makes sense when you have more than 3 users and want to avoid per-seat costs, when data residency requires keeping network topology off third-party servers, or when you want full auditability of your coordination logs. The clients are identical — switching from Tailscale Cloud to Headscale means re-running tailscale up --login-server on each device, nothing more.

Deploy Headscale on your VPS in one click

Self-host your Tailscale control server with unlimited users and no cloud dependency. ServOrbit provisions a ready-to-use Headscale instance — config generated, HTTPS ready, first auth key printed in the job output.

Need help?

Browse our help center and FAQ, or reach our team — callback, WhatsApp or email. Support in French, English and Arabic.