English | 简体中文 | 繁體中文 | Русский
Also available: Headscale server on Docker.
Headscale server installer for Ubuntu, Debian, AlmaLinux, Rocky Linux, CentOS, RHEL, Fedora and openSUSE.
This script installs and configures Headscale — a self-hosted, open-source implementation of the Tailscale coordination server. Connect all your devices using the official Tailscale client apps, with your own server in control.
See also: WireGuard, OpenVPN and IPsec VPN server auto setup scripts.
- Fully automated Headscale server setup, no user input needed
- Supports interactive install using custom options
- Supports managing users, nodes and pre-auth keys
- Downloads the official Headscale binary with checksum verification
- Installs Headscale as a systemd service with a dedicated system user
- Configures firewall rules automatically (firewalld or iptables)
- A Linux server (cloud server, VPS or dedicated server)
- A publicly reachable domain name with HTTPS is strongly recommended for production use
Note: Without HTTPS some Tailscale clients may not connect properly. See TLS and reverse proxy for setup options.
Download the script on your Linux server:
wget -O headscale.sh https://github.com/hwdsl2/headscale-install/raw/main/headscale-install.shOption 1: Auto install using default options.
sudo bash headscale.sh --autoOption 2: Interactive install using custom options.
sudo bash headscale.shYou can customize the following options: server URL, TCP port, initial username and MagicDNS base domain.
Click here if you are unable to download.
You may also use curl to download:
curl -fL -o headscale.sh https://github.com/hwdsl2/headscale-install/raw/main/headscale-install.shIf you are unable to download, open headscale-install.sh, then click the Raw button on the right. Press Ctrl/Cmd+A to select all, Ctrl/Cmd+C to copy, then paste into your favorite editor.
View usage information for the script.
Usage: bash headscale.sh [options]
Options:
--adduser [user name] add a new user
--deleteuser [user name] delete a user (and all their nodes and keys)
--listusers list all users
--listnodes list all registered nodes
--listnodes --user [name] list nodes for a specific user
--deletenode [node ID] delete a node by its numeric ID
--createkey --user [name] create a reusable pre-auth key for a user
--listkeys list pre-auth keys (all users)
--listkeys --user [name] list pre-auth keys for a specific user
--uninstall remove Headscale and delete all configuration
-y, --yes assume "yes" as answer to prompts
-h, --help show this help message and exit
Install options (optional):
--auto auto install Headscale using default or custom options
--serverurl [URL] server URL (e.g. https://hs.example.com)
--port [number] TCP port for Headscale (1-65535, default: 8080)
--username [name] name for the initial user (default: admin)
--basedomain [domain] MagicDNS base domain (default: headscale.internal)
To customize options, you may also run this script without arguments.
On first run, the script:
- Downloads and installs the Headscale binary
- Creates a
headscalesystem user and group - Writes the configuration to
/etc/headscale/config.yaml - Installs and starts the
headscalesystemd service - Creates the initial user and prints a reusable pre-auth key
Copy the pre-auth key from the output and connect a device with the official Tailscale client:
tailscale up --login-server https://hs.example.com --authkey <key-from-output>After setup, run the script again to manage your server.
Add a user:
sudo bash headscale.sh --adduser aliceCreate a pre-auth key for a user:
sudo bash headscale.sh --createkey --user aliceList all users:
sudo bash headscale.sh --listusersList all registered nodes:
sudo bash headscale.sh --listnodesList nodes for a specific user:
sudo bash headscale.sh --listnodes --user aliceDelete a node by ID:
sudo bash headscale.sh --deletenode 3List pre-auth keys:
sudo bash headscale.sh --listkeysRemove Headscale:
sudo bash headscale.sh --uninstallYou may also run the script without arguments for an interactive management menu.
Tailscale clients require HTTPS for full functionality. The recommended setup is a reverse proxy in front of Headscale that handles TLS, then pass --serverurl https://hs.example.com during install (or set server_url in /etc/headscale/config.yaml and restart the service).
Example with Caddy (automatic TLS via Let's Encrypt):
hs.example.com {
reverse_proxy localhost:8080
}
Example with nginx:
server {
listen 443 ssl;
server_name hs.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 3600s;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}Firewall ports to open:
| Port | Protocol | Purpose |
|---|---|---|
8080 |
TCP | Headscale coordination server (or your reverse proxy port) |
443 |
TCP | HTTPS (if using a reverse proxy) |
The configuration file is at /etc/headscale/config.yaml. Edit this file to change settings such as the server URL, base domain or DNS servers, then restart the service:
sudo systemctl restart headscaleCheck service status and logs:
sudo systemctl status headscale
sudo journalctl -u headscale -n 50sudo bash headscale.sh --auto \
--serverurl https://hs.example.com \
--port 8080 \
--username admin \
--basedomain headscale.internalAll install options are optional when using --auto. If --serverurl is not provided, the server's public IP address is auto-detected and HTTP is used (not recommended for production).
Copyright (C) 2026 Lin Song
This work is licensed under the Creative Commons Attribution-ShareAlike 4.0 International License.
Headscale is Copyright (c) 2020, Juan Font, and is distributed under the BSD 3-Clause License.
Tailscale® is a registered trademark of Tailscale Inc. This project is not affiliated with or endorsed by Tailscale Inc.
