How to Install Headscale on Debian: Self-Hosted Tailscale Control Server
Headscale is an open source, self-hosted implementation of the Tailscale control server. Tailscale builds a secure, WireGuard-based mesh network (a “tailnet”) between your machines, and the control server is the coordination plane that handles authentication, key exchange and the network map. Headscale lets you run that coordination plane yourself, keeping the coordination of your private network entirely under your own control.
For homelabs, small teams and privacy-conscious operators, Headscale is a compelling alternative to the hosted Tailscale coordination service: a single Go binary, a SQLite (or PostgreSQL) database, and standard Tailscale clients on every node. You keep using the official tailscale client on your laptops, phones and servers, but they log in against your own server instead of a third party.
Headscale is not packaged in the official Debian repositories, and building it from source means pulling in a Go toolchain and tracking releases by hand. The unofficial deb.griffo.io repository solves this: it ships an up-to-date, prebuilt Headscale package that installs cleanly with apt, complete with a systemd service and a sensible default configuration.
Install the Latest Headscale on Debian: The Short Version
If you only came for the commands, this adds the repository and installs the latest Headscale .deb package on Debian:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null
sudo apt update
sudo apt install headscale
The rest of this guide explains what each command does, how to verify the install, how to keep Headscale up to date, and what to check when something goes wrong.
What Makes Headscale Special?
- 🔐 Self-hosted control plane - Run the coordination server for your own private mesh, no third-party dependency
- 🌐 Standard Tailscale clients - Works with the official clients on Linux, macOS, Windows, iOS and Android
- 🔑 Multiple auth backends - Pre-authentication keys, OpenID Connect (OIDC) and CLI-driven node registration
- 🧩 ACL policy support - Fine-grained access control lists to segment which nodes can reach which
- 📡 Built-in DERP support - Relay traffic when a direct WireGuard path cannot be established
- 🗂️ Users and namespaces - Organise nodes by user for multi-tenant style separation
- 🪶 Lightweight footprint - A single binary backed by SQLite; comfortable on a small VPS
- 📦 MagicDNS and routes - Advertise subnet routes and exit nodes across your tailnet
Why Use the deb.griffo.io Repository?
The deb.griffo.io repository offers a clean, maintainable path to installing Headscale:
- Easy installation and updates through the standard APT package manager
- Automatic dependency management handled by the packaging
- Always tracks upstream releases so you stay current with Headscale
- No compiling from source and no Go toolchain to manage
- Works across supported Debian releases (Bookworm, Trixie and Sid)
Prerequisites
Before you begin, make sure you have:
- A Debian-based system (Bookworm 12, Trixie 13, or Sid)
sudoprivilegescurlinstalled (install withsudo apt install curlif needed)- A domain name or stable IP for the server URL that your nodes can reach
Step 1: Add the deb.griffo.io Repository
Add the repository GPG key and source definition to your system:
# Create the keyrings directory
sudo install -d -m 0755 /etc/apt/keyrings
# Download and install the repository GPG key
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
# Add the repository (auto-detects your distro codename)
echo "deb [signed-by=/etc/apt/keyrings/deb.griffo.io.gpg] https://deb.griffo.io/apt $(lsb_release -sc 2>/dev/null) main" | sudo tee /etc/apt/sources.list.d/deb.griffo.io.list > /dev/null
# Update the package list
sudo apt update
Here is what each step does:
- Keyrings directory: Creates
/etc/apt/keyringswith correct permissions to hold the repository key. - GPG key: Downloads the signing key and stores it in de-armoured form so APT can verify package signatures.
- Repository: Registers the repository, using
lsb_release -scto insert your Debian codename automatically. - Update: Refreshes the package index so the new packages become visible.
Step 2: Update the Package List
If you skipped the final command above, refresh the index now:
sudo apt update
Step 3: Install Headscale
Install Headscale with a single command:
sudo apt install headscale
APT downloads and installs the latest packaged version along with its systemd unit and a default configuration under /etc/headscale.
Step 4: Verify the Installation
Confirm Headscale is installed and check the version:
headscale version
You should see output similar to:
v0.26.1
Getting Started with Headscale
Headscale runs as a long-lived service and is then driven through its command line for day-to-day administration. The following walk-through takes you from a running server to a connected node.
Configure the Server
The primary configuration file lives at /etc/headscale/config.yaml. At a minimum, set server_url to the address your nodes will use, and confirm the listen address:
# /etc/headscale/config.yaml
server_url: https://headscale.example.com
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090
database:
type: sqlite
sqlite:
path: /var/lib/headscale/db.sqlite
dns:
magic_dns: true
base_domain: tailnet.example.com
Validate the file before starting the service:
headscale configtest
Start and Enable the Service
Enable the packaged systemd unit so Headscale starts on boot and immediately begins running:
sudo systemctl enable --now headscale
sudo systemctl status headscale
Follow the logs with sudo journalctl -u headscale -f while you get set up.
Create a User and Register a Node
Headscale groups nodes under users. Create one, then list them:
# Create a user
sudo headscale users create alice
# List users
sudo headscale users list
On the machine you want to join, install the official Tailscale client and point it at your server:
sudo tailscale up --login-server https://headscale.example.com
Tailscale prints a registration command containing a machine key. Complete the join from the Headscale host:
sudo headscale nodes register --user alice --key <machine-key-from-client>
List the connected nodes to confirm:
sudo headscale nodes list
Use Pre-Authentication Keys
For unattended machines and automation, pre-auth keys are far more convenient than interactive registration:
# Create a reusable key that lasts 24 hours
sudo headscale preauthkeys create --user alice --reusable --expiration 24h
# List existing keys
sudo headscale preauthkeys list --user alice
Then bring the client up non-interactively:
sudo tailscale up --login-server https://headscale.example.com --authkey <preauth-key>
Advertise Routes and Exit Nodes
A node can share a subnet or act as an exit node for the tailnet. Advertise from the client, then approve on the server:
# On the node
sudo tailscale up --login-server https://headscale.example.com --advertise-routes=192.168.1.0/24
# On the Headscale host, enable the advertised route
sudo headscale nodes list-routes
sudo headscale nodes approve-routes --identifier 1 --routes 192.168.1.0/24
Keeping Headscale Updated
Because Headscale is installed from the repository, updates arrive through your normal system upgrade:
sudo apt update && sudo apt upgrade
After a major upgrade, run headscale configtest and check the release notes, since configuration keys occasionally change between versions.
Other Tools from deb.griffo.io
The deb.griffo.io repository packages many other self-hosting and terminal tools. If you are running Headscale, these pair well:
- Forgejo - A self-hosted lightweight Git forge for your code
- Garage - An S3-compatible distributed object storage service
- k9s - A terminal UI to interact with your Kubernetes clusters
- Lazydocker - A simple terminal UI for Docker and docker-compose
Troubleshooting
GPG or Key Issues
If APT reports the repository is not signed or the key cannot be verified, re-add the signing key:
sudo install -d -m 0755 /etc/apt/keyrings
curl -fsSL https://deb.griffo.io/EA0F721D231FDD3A0A17B9AC7808B4DD62C41256.asc | sudo gpg --dearmor --yes -o /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update
Package Not Found
If apt install headscale reports the package is unavailable:
- Run
sudo apt updateagain after adding the repository. - Confirm your Debian release is supported (Bookworm, Trixie or Sid).
- Inspect the source file:
cat /etc/apt/sources.list.d/deb.griffo.io.list.
Nodes Cannot Connect
If clients fail to register or drop off the tailnet, the cause is almost always reachability or the server_url:
- Ensure
server_urlin/etc/headscale/config.yamlmatches the exact URL clients use, including scheme and port. - Confirm the port is reachable through any firewall or reverse proxy, and that TLS terminates correctly.
- Check
sudo journalctl -u headscale -fwhile a client runstailscale upto see the rejection reason.
Uninstalling
To remove Headscale:
sudo apt remove headscale
To also remove the repository definition and key:
sudo rm /etc/apt/sources.list.d/deb.griffo.io.list
sudo rm /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update
State under /var/lib/headscale and configuration under /etc/headscale are left in place; delete them manually if you no longer need them.
Conclusion
Headscale gives you the coordination server behind a Tailscale mesh network without handing that role to anyone else, and the deb.griffo.io repository makes getting it onto Debian a one-line apt install. You get a single lightweight binary, a proper systemd service, and updates that flow through the same upgrade process as the rest of your system.
Once your control server is running, adding machines is as simple as pointing the standard Tailscale client at your server_url and registering the node. From there, ACLs, subnet routes and exit nodes let your private network grow exactly as far as you need, entirely on infrastructure you own.
Frequently Asked Questions
How do I install the latest Headscale on Debian?
Add the deb.griffo.io APT repository and its signing key, then run sudo apt install headscale. The repository tracks upstream Headscale releases, so you get the latest packaged version rather than a build frozen when your distribution was released.
Is there a .deb package for Headscale?
Yes. deb.griffo.io publishes Headscale as a signed .deb for Debian. You could download that .deb and install it by hand, but adding the repository is the better option: APT then resolves dependencies and picks up new versions on its own.
How do I update Headscale to the latest version?
Run sudo apt update && sudo apt upgrade. Once Headscale is installed from APT there is no separate updater to remember, since new releases arrive with the rest of your system updates.
How do I install Headscale on Ubuntu?
Exactly the same way; lsb_release -sc simply resolves to a different codename. There is a companion guide with the Ubuntu specifics: How to install Headscale on Ubuntu.
Which Debian releases are supported?
Bookworm 12, Trixie 13 and Sid. Because the repository line is built from lsb_release -sc, the matching suite is selected for you.
Resources
- Headscale Documentation
- Headscale GitHub Repository
- Tailscale Documentation
- deb.griffo.io Repository
Disclaimer: The deb.griffo.io repository is an unofficial community project and is not affiliated with the official Debian or Ubuntu projects, or with the upstream Headscale project.