Headscale with Headplane Web-UI

Headscale is a self-hosted, open-source coordination server for Tailscale-compatible private networks, allowing you to create secure mesh VPNs without relying on external services. Combined with Headplane, a modern web-based management UI, this stack provides full control over your private network infrastructure with an easy-to-use interface. This template includes: Headscale server for managing secure, WireGuard-based private networks Headplane dashboard for visual management of nodes, users, and routes Persistent storage for configuration and network state UDP support for NAT traversal and reliable peer connectivity Metrics endpoint for monitoring and observability Perfect for developers, homelab users, and teams who want a fully self-hosted, privacy-focused VPN solution with centralized management and a clean web interface.

yaml

docker-compose.yml

services:
  headscale:
    image: headscale/headscale:stable
    restart: unless-stopped
    container_name: headscale
    labels:
      me.tale.headplane.target: headscale
    ports:
      - "8800:8800"
      - 3478:3478/udp
      - "9090:9090"
    volumes:
      - ./config:/etc/headscale
      - ./lib:/var/lib/headscale
      - ./run:/var/run/headscale
    command: serve
    sysctls:
      - net.ipv4.ip_forward=1
      - net.ipv6.conf.all.forwarding=1
  headplane:
    image: ghcr.io/tale/headplane:latest
    container_name: headplane
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - ./headplane_config:/etc/headplane
      - ./headplane_lib:/var/lib/headplane
      - ./config:/etc/headscale
      - /var/run/docker.sock:/var/run/docker.sock:ro

.ENV

.env example

# No environment variables detected

deployment

Quick Start

  1. Create a working directory named after the service.
  2. Copy the compose file and generated `.env` into that directory.
  3. Review the variables and replace placeholders with real values.
  4. Run `docker compose up -d`.
mkdir headscale-headplane
cd headscale-headplane
# create docker-compose.yml
# create .env
docker compose up -d