Skip to content
Live $100 credit at signup, up to $300 total Offer ends December 31, 2026 Get started →

Headplane

Headplane is a feature-complete web UI for Headscale, the open-source, self-hosted implementation of the Tailscale control server. It lets you manage nodes, pre-auth keys, ACLs, and DNS from a browser instead of the Headscale CLI. Headplane does not replace Headscale. It manages a running Headscale server, so this image ships both together.

ComponentVersion
Headplane0.7.0
Headscale0.29.2
DockerLatest stable
Ubuntu24.04 LTS

Headplane cannot run on its own, because every action it performs is an API call to Headscale. This image runs the Headscale control server and the Headplane UI together as a Docker Compose stack.

ResourceMinimumRecommended
vCPU12
RAM1 GB2 GB
Storage10 GB20 GB

These values are optional during marketplace deployment. Leave them blank to use the VM’s own address.

VariableDescription
HEADSCALE_SERVER_URLPublic URL your devices use to reach Headscale, such as an HTTPS domain
HEADPLANE_BASE_URLPublic URL the Headplane UI is served from

Set these when you front the VM with a DNS name or a TLS reverse proxy. HEADSCALE_SERVER_URL must be an address reachable by your devices, otherwise nodes fail to register.

ssh ubuntu@<your-vm-ip>

On the first boot, a setup script writes the VM address into the Headscale and Headplane configs, generates a session secret, starts both services, creates a Headscale user named default, and mints an API key. This takes 1-2 minutes. Track progress:

journalctl -u headplane-first-boot.service -f

The login message (MOTD) confirms when Headplane is ready and prints the API key.

The key is also written to a root-only file:

sudo cat /etc/headplane/credentials.txt

Open a browser and navigate to:

http://<your-vm-ip>:3000/admin

Headplane authenticates against Headscale with an API key. Paste the key from the previous step into the login form. The key expires after 90 days. Mint a new one at any time:

docker exec headscale headscale apikeys create --expiration 90d

Point any Tailscale client at your Headscale server:

tailscale up --login-server http://<your-vm-ip>:8080

Approve the node from the Headplane UI, or list nodes from the CLI:

docker exec headscale headscale nodes list

Headscale and Headplane run as a Docker Compose stack in /opt/headplane.

# Check status
cd /opt/headplane && docker compose ps
# Restart
cd /opt/headplane && docker compose restart
# View logs
cd /opt/headplane && docker compose logs -f headscale

Headscale’s configuration is at /opt/headplane/headscale/config/config.yaml and its database under /opt/headplane/headscale/data. ACL policies are stored in the database and remain editable from the Headplane UI.

Ports 3000 (Headplane UI) and 8080 (Headscale) are open on the VM’s network interface. UFW is enabled and allows those ports plus SSH (port 22).

Your devices must reach Headscale on port 8080, but the Headplane UI does not need to be public.

To restrict the UI to a specific IP:

sudo ufw delete allow 3000/tcp
sudo ufw allow from <trusted-ip> to any port 3000

For production use, point a DNS record at the VM and terminate TLS with a reverse proxy (Caddy, nginx, or Traefik). Set HEADSCALE_SERVER_URL and HEADPLANE_BASE_URL to the HTTPS URLs, and set cookie_secure: true in /opt/headplane/headplane/config.yaml.

Last updated: