How to Install Headplane a Headscale WebUI

Managing your tailnet through the terminal may be a scary and complicated thing for some.
That is why in this guide we will show you how to install Headplane, an easy-to-install Headscale WebUI for managing your tailnet.

If you want more information on what Tailscale/Headscale is you can check our other guides here -
Hosting Headscale In a Container With Docker
Using Tailscale/Headscale as a traditional VPN

Prerequisites

The WebUI itself can be run anywhere but we recommend running it on the same host that runs the headscale server.

You can take a look at our special VPN server plans starting from €2.49 here

Installing Headplane

  1. Create a folder named headplane and cd into it:
mkdir headplane && cd headplane
  1. Create a file named docker-compose.yml
nano docker-compose.yml
  1. Paste the following:
services:
  headplane:
    container_name: headplane
    image: ghcr.io/tale/headplane:0.3.9
    restart: unless-stopped
    volumes:
      - '/root/headscale/lib:/var/lib/headscale'
      - '/root/headscale/config:/etc/headscale'
      - '/var/run/docker.sock:/var/run/docker.sock:ro'
    ports:
      - "100.64.0.1:2000:2000"
    environment:
      # This is always required for Headplane to work
      COOKIE_SECRET: 'abcddgffgfsefghijklm12345'

      HEADSCALE_INTEGRATION: 'docker'
      HEADSCALE_CONTAINER: 'headscale'
      DISABLE_API_KEY_LOGIN: 'true'
      HOST: '0.0.0.0'
      PORT: '2000'

      # Only set this to false if you aren't behind a reverse proxy
      COOKIE_SECURE: 'false'

      # Overrides the configuration file values if they are set in config.yaml
      # If you want to share the same OIDC configuration you do not need this
      OIDC_CLIENT_ID: 'headscale'
      OIDC_ISSUER: 'https://sso.example.com'
      OIDC_CLIENT_SECRET: 'super_secret_client_secret'

      # This NEEDS to be set with OIDC, regardless of what's in the config
      # This needs to be a very long-lived (999 day) API key used to create
      # shorter ones for OIDC and allow the OIDC functionality to work
      ROOT_API_KEY: 'abcdefghijklmnopqr12345'
This config will not work out of the box and will need changes as stated below!

This config will need several changes:

  1. Change the first two volumes to point to your headscale config and lib folders
  2. Change the ports section as you wish - the current setup allows Headplane to be only accessible on tailnet IP 100.64.0.1 on port 2000
    If you want this to be public just make the line instead of
    "100.64.0.1:2000:2000" to "2000:2000"
  3. Change both COOKIE_SECRET and ROOT_API_KEY
  4. Comment out lines 25 to 29 if you plan to use the default headscale OIDC or if you manage OIDC within headscale
  5. Change the name of the headscale container if it's not named "headscale"
  6. If you use Watchtower you can add the following to disable it from auto-updating
    labels:
      - "com.centurylinklabs.watchtower.enable=false"

Now you are ready to start the container with this command:

docker compose up -d

Using Headplane

Once the docker container starts you can navigate to http://<your-ip>:2000/admin and it will prompt you for an API key
To get this key enter the headscale host and run the following command:

docker exec -it headscale headscale apikeys create

Or if you are running a binary of headscale:

headscale apikeys create