Files
wild-directory/headscale/versions/1/README.md
2026-06-19 21:33:05 +00:00

2.4 KiB

Headscale

Headscale is an open-source, self-hosted implementation of the Tailscale control plane. It lets you run your own private WireGuard-based mesh VPN using the Tailscale client.

Configuration

Key settings in config.yaml:

  • domain - Where the Headscale control plane API is accessible
  • vpnBaseDomain - Base domain for MagicDNS hostnames assigned to nodes (default: vpn.{your-cloud-domain})
  • storage - Persistent volume size (default: 2Gi)

First-Time Setup

  1. Add and deploy the app:

    wild app add headscale
    wild app deploy headscale
    
  2. Create a user (namespace) in Headscale:

    kubectl exec -n headscale deploy/headscale -- headscale users create <username>
    
  3. Generate a pre-auth key for that user:

    kubectl exec -n headscale deploy/headscale -- headscale preauthkeys create --user <user-id> --reusable --expiration 24h
    

    Note: --user requires the numeric user ID, not the username. Run headscale users list to get the ID.

  4. On each device you want to join the VPN, install the Tailscale client and connect it to your Headscale instance:

    tailscale up --login-server https://<your-headscale-domain> --authkey <preauthkey>
    

Registering Nodes via Browser Auth

If a Tailscale client connects without a pre-auth key, it shows an auth URL in its logs. Register that node with:

kubectl exec -n headscale deploy/headscale -- headscale nodes register --auth-id <hskey-authreq-XXXX> --user <username>

Note: --user here accepts the username string (not the numeric ID).

Useful Commands

# List users
kubectl exec -n headscale deploy/headscale -- headscale users list

# List connected nodes
kubectl exec -n headscale deploy/headscale -- headscale nodes list

# Create a pre-auth key (requires numeric user ID)
kubectl exec -n headscale deploy/headscale -- headscale preauthkeys create --user <id> --reusable

# Delete a node
kubectl exec -n headscale deploy/headscale -- headscale nodes delete --identifier <node-id>

Notes

  • Headscale uses SQLite by default — no external database dependency
  • Configuration is managed via a ConfigMap (headscale-config) — changes require restarting the pod
  • In Headscale v0.29+, different commands accept different user identifier types: preauthkeys and users destroy require the numeric ID, while nodes register accepts the username string