Why Self-Host with Headscale?
- • Complete data sovereignty: Your server, your control
- • No device limits: Connect unlimited devices
- • No subscription fees: Just your VPS cost
- • Full customization: ACLs, DNS, network policies
- • Compatible clients: Works with official Tailscale apps
- • WireGuard-based: Modern, fast, secure VPN protocol
Prerequisites
Before starting, ensure you have:
VPS Requirements
- • Ubuntu 24.04 LTS or Debian 12+
- • 1GB RAM minimum
- • 1 vCPU
- • 10GB+ SSD storage
Additional Requirements
- • Domain pointing to VPS IP
- • (e.g., headscale.yourdomain.com)
- • SSH root or sudo access
- • Basic Linux knowledge
| Requirement | Specification |
|---|---|
| RamNode VPS | 1GB RAM, 1 vCPU, 10GB storage |
| Operating System | Ubuntu 24.04 LTS or Debian 12+ |
| Domain Name | Subdomain pointing to VPS IP |
| SSH Access | Root or sudo access |
System Preparation
Connect to your RamNode VPS via SSH and update the system:
sudo apt update && sudo apt upgrade -ysudo apt install -y curl wget gnupg apt-transport-httpsInstall Headscale
Headscale provides official .deb packages for Debian-based systems:
# Get latest version
VERSION=$(curl -s "https://api.github.com/repos/juanfont/headscale/releases/latest" | grep '"tag_name"' | sed -E 's/.*"([^"]+)".*/\1/' | sed 's/v//')
echo "Installing Headscale v${VERSION}"
# Download the .deb package
wget -O headscale.deb "https://github.com/juanfont/headscale/releases/download/v${VERSION}/headscale_${VERSION}_linux_amd64.deb"sudo apt install -f ./headscale.debWhat the Package Creates:
- A dedicated
headscaleuser - Configuration directory at
/etc/headscale/ - A systemd service file for automatic startup
Configure Headscale
Edit the main configuration file:
sudo nano /etc/headscale/config.yaml| Setting | Value |
|---|---|
| server_url | https://headscale.yourdomain.com |
| listen_addr | 0.0.0.0:8080 |
| metrics_listen_addr | 127.0.0.1:9090 |
| database.type | sqlite (recommended) |
| database.path | /var/lib/headscale/db.sqlite |
server_url: https://headscale.yourdomain.com
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 127.0.0.1:9090
database:
type: sqlite
path: /var/lib/headscale/db.sqlite
prefixes:
v4: 100.64.0.0/10
v6: fd7a:115c:a1e0::/48
dns:
magic_dns: true
base_domain: ts.yourdomain.com
nameservers:
global:
- 1.1.1.1
- 8.8.8.8Set Up Reverse Proxy with Caddy
Caddy provides automatic HTTPS with Let's Encrypt certificates:
sudo apt install -y debian-keyring debian-archive-keyring
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/gpg.key' | sudo gpg --dearmor -o /usr/share/keyrings/caddy-stable-archive-keyring.gpg
curl -1sLf 'https://dl.cloudsmith.io/public/caddy/stable/debian.deb.txt' | sudo tee /etc/apt/sources.list.d/caddy-stable.list
sudo apt update
sudo apt install caddysudo nano /etc/caddy/Caddyfileheadscale.yourdomain.com {
reverse_proxy localhost:8080
}sudo systemctl restart caddyConfigure Firewall
Open the necessary ports using UFW:
sudo ufw allow 80/tcp # HTTP (for Let's Encrypt)
sudo ufw allow 443/tcp # HTTPS
sudo ufw allow 22/tcp # SSH (don't lock yourself out!)
sudo ufw enable⚠️ Important: Make sure you allow SSH (port 22) before enabling UFW to avoid locking yourself out of your server.
Start Headscale
Enable and start the Headscale service:
sudo systemctl enable headscale
sudo systemctl start headscalesudo systemctl status headscaleVerify Web Accessibility:
Visit https://headscale.yourdomain.com/windows in your browser—this should show client setup instructions.
Create Users and Pre-Auth Keys
In Headscale, 'users' are equivalent to Tailscale's 'tailnets':
sudo headscale users create myusersudo headscale users listsudo headscale preauthkeys create --user myuser --reusable --expiration 24hPre-Auth Key Options
--reusable: Key can be used for multiple devices--expiration: Set key validity period (e.g., 24h, 7d)--ephemeral: Nodes will be removed when they go offline
Connect Clients
Install the official Tailscale client and connect to your Headscale server:
Linux
curl -fsSL https://tailscale.com/install.sh | shsudo tailscale up --login-server=https://headscale.yourdomain.com --authkey=YOUR_PREAUTH_KEYInteractive Registration (Without Pre-Auth Key)
sudo tailscale up --login-server=https://headscale.yourdomain.comThis opens a browser with a registration URL containing your machine key. On your Headscale server, approve the registration:
sudo headscale nodes register --user myuser --key YOUR_MACHINE_KEYWindows / macOS / iOS / Android
Download the official Tailscale client from tailscale.com/download. When prompted to log in, use your Headscale server URL or configure the --login-server parameter.
Verify Connectivity
Confirm your mesh network is working:
sudo headscale nodes listtailscale statusTest Connectivity
Ping another device on your tailnet using its Tailscale IP (e.g., 100.64.x.x) or MagicDNS hostname.
Install Headscale-UI
For a graphical management interface, deploy the community-maintained Headscale-UI:
sudo headscale apikeys createdocker run -d \
--name headscale-ui \
-p 8443:443 \
ghcr.io/gurucomputing/headscale-ui:latest⚠️ Note: Headscale-UI must be served on the same subdomain as Headscale (or use CORS headers via reverse proxy) to function properly.
Troubleshooting
Service Won't Start
sudo journalctl -u headscale -fConfiguration Validation
sudo headscale configtestClient Won't Connect
- Ensure your domain's DNS A record points to your VPS IP
- Verify Caddy obtained SSL certificates (check
/var/log/caddy/) - Check that ports 80 and 443 are open
- Confirm the
server_urlin config.yaml matches your actual domain
Maintenance and Backups
Regular backups ensure you can recover your network configuration:
# Backup the database
sudo cp /var/lib/headscale/db.sqlite /backup/headscale-$(date +%Y%m%d).sqlite
# Backup configuration
sudo cp /etc/headscale/config.yaml /backup/Upgrading Headscale
To upgrade, download the new .deb package and install it, then restart the service. Always check the release notes for breaking changes between versions.
Deployment Complete!
You now have a fully functional Headscale server running on your RamNode VPS, providing complete control over your mesh VPN infrastructure. Your devices can securely communicate with each other regardless of their physical location, without relying on third-party coordination services.
For advanced configurations including ACL policies, subnet routing, exit nodes, and OIDC authentication, refer to the official Headscale documentation.
