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)
  • sudo privileges
  • curl installed (install with sudo apt install curl if 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:

  1. Keyrings directory: Creates /etc/apt/keyrings with correct permissions to hold the repository key.
  2. GPG key: Downloads the signing key and stores it in de-armoured form so APT can verify package signatures.
  3. Repository: Registers the repository, using lsb_release -sc to insert your Debian codename automatically.
  4. 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>

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:

  1. Run sudo apt update again after adding the repository.
  2. Confirm your Debian release is supported (Bookworm, Trixie or Sid).
  3. 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:

  1. Ensure server_url in /etc/headscale/config.yaml matches the exact URL clients use, including scheme and port.
  2. Confirm the port is reachable through any firewall or reverse proxy, and that TLS terminates correctly.
  3. Check sudo journalctl -u headscale -f while a client runs tailscale up to 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


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.