How to Install Headscale on Ubuntu: Self-Hosted Tailscale Control Server
Headscale is an open source, self-hosted implementation of the Tailscale control server. In a Tailscale network, individual machines form a secure WireGuard mesh, but they still need a coordination server to authenticate peers, exchange keys and distribute the network map. Headscale is that coordination server, reimplemented as free software you can run on your own Ubuntu box.
If you like the ergonomics of Tailscale but would rather not depend on a hosted coordination service, Headscale is the natural answer. Your laptops, servers and phones keep running the official tailscale client; they simply authenticate against a server you control. A homelab, a small company, or a single VPS is more than enough to host a full tailnet.
Ubuntu does not ship Headscale in its official archives, and compiling it yourself means installing Go and manually chasing releases. The unofficial deb.griffo.io repository removes that friction by publishing a prebuilt, regularly updated Headscale package that installs with apt, bundled with a systemd unit and a working default configuration.
Install the Latest Headscale on Ubuntu: The Short Version
If you only came for the commands, this adds the repository and installs the latest Headscale .deb package on Ubuntu:
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 - You own the coordination server for your private mesh network
- ๐ Standard Tailscale clients - Compatible with the official clients across every major platform
- ๐ Flexible authentication - Pre-auth keys, OpenID Connect (OIDC) and CLI node registration
- ๐งฉ ACL policies - Access control lists to decide which nodes may reach which services
- ๐ก DERP relay support - Falls back to relayed traffic when a direct path is not possible
- ๐๏ธ User-based organisation - Group machines by user for clean multi-tenant separation
- ๐ชถ Small and simple - A single Go binary with SQLite; happy on modest hardware
- ๐ฆ Routes, exit nodes and MagicDNS - Full tailnet features without the hosted control plane
Why Use the deb.griffo.io Repository?
Using deb.griffo.io to install Headscale on Ubuntu brings several benefits:
- Easy installation and updates through the APT package manager
- Automatic dependency management handled by the packaging
- Always tracks upstream releases so your control server stays current
- No compiling from source and no Go toolchain to maintain
- Works across supported Ubuntu releases with the codename detected automatically
Prerequisites
Before you start, make sure you have:
- An Ubuntu system (Jammy 22.04 LTS, Noble 24.04 LTS, or newer)
sudoprivilegescurlinstalled (install withsudo apt install curlif needed)- A reachable domain name or stable IP for your server URL
Step 1: Add the deb.griffo.io Repository
Register the repository GPG key and source on 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
A quick breakdown of the commands:
- Keyrings directory: Ensures
/etc/apt/keyringsexists with the right permissions. - GPG key: Fetches the signing key and stores it de-armoured for APT to verify signatures.
- Repository: Adds the source line, with
lsb_release -scfilling in your Ubuntu codename (for examplenoble). - Update: Reads the new repository metadata so the packages appear.
Step 2: Update the Package List
If you did not run the last command above, do so now:
sudo apt update
Step 3: Install Headscale
Install the package:
sudo apt install headscale
APT pulls in the latest packaged Headscale together with its systemd service and the default configuration under /etc/headscale.
Step 4: Verify the Installation
Check that Headscale is present and print its version:
headscale version
Expected output looks like:
v0.26.1
Getting Started with Headscale
Headscale runs as a background service that you administer from the command line. The steps below take you from an installed package to a fully connected node on Ubuntu.
Enable the Service
The package ships a systemd unit. Enable it so Headscale starts at boot and runs immediately:
sudo systemctl enable --now headscale
sudo systemctl status headscale
Tail the logs while you configure things:
sudo journalctl -u headscale -f
Configure the Server
The configuration file is /etc/headscale/config.yaml. The most important value is server_url, the address your nodes will contact:
# /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
Whenever you edit the file, validate it and restart the service:
headscale configtest
sudo systemctl restart headscale
Create a User and Register a Node
Every node belongs to a user in Headscale. Create one first:
# Create a user
sudo headscale users create bob
# List users
sudo headscale users list
On the machine joining the tailnet, install the official Tailscale client and log in against your server:
sudo tailscale up --login-server https://headscale.example.com
The client prints a machine key. Register it from the Headscale host:
sudo headscale nodes register --user bob --key <machine-key-from-client>
sudo headscale nodes list
Use Pre-Authentication Keys
For servers and scripted provisioning, pre-auth keys avoid the interactive step entirely:
# Create a reusable key valid for 24 hours
sudo headscale preauthkeys create --user bob --reusable --expiration 24h
# List keys for the user
sudo headscale preauthkeys list --user bob
Bring a node up without any prompts:
sudo tailscale up --login-server https://headscale.example.com --authkey <preauth-key>
Advertise Subnet Routes
A node can expose a local subnet to the rest of the tailnet. Advertise it on the client, then approve it on the server:
# On the node
sudo tailscale up --login-server https://headscale.example.com --advertise-routes=10.0.0.0/24
# On the Headscale host
sudo headscale nodes list-routes
sudo headscale nodes approve-routes --identifier 1 --routes 10.0.0.0/24
Keeping Headscale Updated
Since Headscale is installed from the repository, it updates alongside the rest of your Ubuntu packages:
sudo apt update && sudo apt upgrade
After upgrading across a major version, run headscale configtest and skim the changelog, as configuration keys are occasionally renamed between releases.
Other Tools from deb.griffo.io
The deb.griffo.io repository packages plenty of complementary self-hosting and infrastructure tools:
- Forgejo - A self-hosted lightweight Git forge for your projects
- 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 complains that the repository is not signed, re-import the key and update:
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 cannot locate the headscale package:
- Re-run
sudo apt updateafter adding the repository. - Verify your Ubuntu release is supported (Jammy, Noble or newer).
- Check the source line:
cat /etc/apt/sources.list.d/deb.griffo.io.list.
Nodes Fail to Register
When clients cannot join or keep dropping, the culprit is usually the server_url or a proxy in front of Headscale:
- Make sure
server_urlexactly matches the URL clients use, includinghttps://and any port. - Confirm the listen port is reachable through UFW or your reverse proxy, and that TLS is valid end to end.
- Watch
sudo journalctl -u headscale -fwhile runningtailscale upon the client to read the rejection message.
Uninstalling
To remove Headscale:
sudo apt remove headscale
To also remove the repository configuration:
sudo rm /etc/apt/sources.list.d/deb.griffo.io.list
sudo rm /etc/apt/keyrings/deb.griffo.io.gpg
sudo apt update
The database under /var/lib/headscale and the configuration under /etc/headscale remain; remove them by hand if you are decommissioning the server for good.
Conclusion
Headscale hands you the coordination server behind a Tailscale mesh without outsourcing that role, and on Ubuntu the deb.griffo.io repository turns installation into a single apt install. You get one small binary, a managed systemd service and updates that ride along with your normal apt upgrade.
With the server running, every new machine is just a tailscale up --login-server away from joining your private network. Layer on ACLs, subnet routes and exit nodes as your needs grow, and you have a self-owned mesh VPN that scales from a single laptop to a full fleet.
Frequently Asked Questions
How do I install the latest Headscale on Ubuntu?
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 Ubuntu. 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 Debian?
Exactly the same way; lsb_release -sc simply resolves to a different codename. There is a companion guide with the Debian specifics: How to install Headscale on Debian.
Which Ubuntu releases are supported?
Jammy 22.04 LTS, Noble 24.04 LTS and newer. 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.