在 Docker 上运行 Headscale 服务器

September 14, 2026 · View on GitHub

English | 简体中文 | 繁體中文 | Русский

在 Docker 上运行 Headscale 服务器

Build Status  Docker Pulls  License: MIT

一个用于运行 Headscale 服务器的 Docker 镜像。Headscale 是 Tailscale 协调服务器的自托管开源实现。使用官方 Tailscale 客户端应用连接所有设备,由你自己的服务器掌控一切。

功能特性:

  • 首次启动时自动生成服务器配置和预授权密钥
  • 通过辅助脚本(hs_manage)管理用户、节点和预授权密钥
  • 支持 MagicDNS,实现网络内主机名无缝解析
  • 通过 GitHub Actions 自动构建和发布
  • 使用 Docker 卷实现数据持久化
  • 多架构支持:linux/amd64linux/arm64

另提供:

📘 Kindle 限时优惠:$0.99/£0.99(仅限美国和英国)。The Self-Hosted AI Builder’s Guide 是一本关于构建、保护和运维自己的私有 AI 技术栈的实用指南。

快速开始

前提条件

强烈建议使用具有域名和 TLS 证书的可公开访问的服务器。请参阅 TLS 与反向代理 了解配置选项。

使用 Docker

创建 vpn.env 文件。HS_SERVER_URL 是 Tailscale 客户端用于连接到你的服务器的 HTTPS URL。有关所有选项,请参阅环境变量

HS_SERVER_URL=https://hs.example.com

运行容器:

docker run \
  --name headscale \
  --restart=always \
  -p 127.0.0.1:8080:8080/tcp \
  -v headscale-data:/var/lib/headscale \
  -v ./vpn.env:/vpn.env:ro \
  -d hwdsl2/headscale-server

注: 使用上述命令时,端口 8080 仅绑定到本地主机。需要在宿主机上运行一个处理 TLS 并将流量转发到 127.0.0.1:8080 的反向代理,Tailscale 客户端才能连接。请参阅 TLS 与反向代理。如需直接对外发布端口,请将 127.0.0.1:8080:8080 替换为 8080:8080

另外,你也可以在不使用 Docker 的情况下安装 Headscale。要了解更多有关如何使用本镜像的信息,请继续阅读以下部分。

首次启动时,容器将:

  1. 根据环境变量生成服务器配置
  2. 创建初始用户(默认:admin
  3. 可重复使用的预授权密钥输出到容器日志

从日志中获取初始预授权密钥:

docker logs headscale
点击查看示例输出。

Headscale 首次运行设置输出,显示初始用户和预授权密钥

使用官方 Tailscale 客户端连接设备:

tailscale up --login-server https://hs.example.com --authkey <日志中的密>

使用 Docker Compose

cp vpn.env.example vpn.env
nano vpn.env        # 至少设置 HS_SERVER_URL
docker compose up -d
docker compose logs headscale

示例 docker-compose.yml(已包含在内):

services:
  headscale:
    image: hwdsl2/headscale-server
    container_name: headscale
    restart: always
    ports:
      - "127.0.0.1:8080:8080/tcp"
    volumes:
      - headscale-data:/var/lib/headscale
      - ./vpn.env:/vpn.env:ro

volumes:
  headscale-data:
    name: headscale-data

社区

下载

Docker Hub 镜像仓库获取镜像:

docker pull hwdsl2/headscale-server

或从 Quay.io 下载:

docker pull quay.io/hwdsl2/headscale-server
docker image tag quay.io/hwdsl2/headscale-server hwdsl2/headscale-server

支持平台:linux/amd64linux/arm64

客户端配置

有关连接客户端的说明,请参阅 Headscale 文档:

环境变量

所有变量均为可选项。HS_SERVER_URL 强烈建议在生产环境中设置。

变量默认值说明
HS_SERVER_URL自动检测Tailscale 客户端连接的 URL(例如 https://hs.example.com)。必须使用 HTTPS 以确保客户端完整功能。
HS_LISTEN_PORT8080服务器监听的 TCP 端口。
HS_METRICS_PORT9090Prometheus 指标端口。设置为空以禁用。
HS_BASE_DOMAINheadscale.internalMagicDNS 主机名的基础域名(例如 myhost.headscale.internal)。不得与 HS_SERVER_URL 中的主机名相同或为其父域名(例如若 HS_SERVER_URL=https://hs.example.com,则不要使用 example.com)。
HS_USERNAMEadmin初始设置时创建的第一个用户名称。
HS_DNS_SRV11.1.1.1通过 MagicDNS 推送给客户端的主 DNS 服务器,支持 IPv4 或 IPv6。
HS_DNS_SRV21.0.0.1通过 MagicDNS 推送给客户端的备用 DNS 服务器。
HS_LOG_LEVELinfo日志级别:panicfatalerrorwarninfodebugtrace
HS_DISABLE_USAGE_COUNTS(未设置)设为 1 可禁用匿名聚合使用计数。

注:env 文件中,可以用单引号括住变量值,例如 VAR='值'。不要在 = 周围添加空格。

每次容器启动时会重新生成配置文件。修改设置时,更新 vpn.env 并重启容器即可。env 文件以绑定挂载方式挂载到容器中,每次重启时自动读取更改,无需重新创建容器。

TLS 与反向代理

Tailscale 客户端在使用 HTTPS 时效果最佳。推荐的配置是在 Headscale 前运行一个负责处理 TLS 终止的反向代理,然后将 HS_SERVER_URL 设置为你的 HTTPS URL。

在反向代理中使用以下地址之一来连接 Headscale 容器:

  • headscale:8080 — 如果反向代理作为容器运行在与 Headscale 相同的 Docker 网络中(例如,在同一个 docker-compose.yml 中定义)。Docker 会自动解析容器名称。
  • 127.0.0.1:8080 — 如果反向代理运行在宿主机上,且端口 8080 已发布(默认 docker-compose.yml 会发布该端口)。

注: 请勿使用通过 docker inspect 获取的容器内部 IP 地址。该地址在每次重新创建容器时都会改变。

使用 CaddyDocker 镜像)的示例(通过 Let's Encrypt 自动申请 TLS,反向代理在相同的 Docker 网络中):

Caddyfile

hs.example.com {
  reverse_proxy headscale:8080
}

使用 nginx 的示例(反向代理在宿主机上):

server {
  listen 443 ssl;
  server_name hs.example.com;

  ssl_certificate     /path/to/cert.pem;
  ssl_certificate_key /path/to/key.pem;

  location / {
    proxy_pass http://127.0.0.1:8080;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_read_timeout 3600s;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
  }
}

vpn.env 中设置 HS_SERVER_URL=https://hs.example.com 并重启容器。

防火墙中需要开放的端口:

端口协议用途
8080TCPHeadscale 协调服务器(或反向代理端口)
443TCPHTTPS(使用反向代理时)
9090TCPPrometheus 指标(可选,默认不发布)

管理服务器

使用 hs_manage 辅助脚本从宿主机管理用户和节点,无需进入容器。

按认证 ID 注册节点:

docker exec headscale hs_manage --registernode <auth-id> --user admin

添加用户:

docker exec headscale hs_manage --adduser alice

删除用户:

docker exec -it headscale hs_manage --deleteuser alice
# 或跳过确认提示:
docker exec headscale hs_manage --deleteuser alice --yes

为用户创建预授权密钥:

docker exec headscale hs_manage --createkey --user alice

列出用户:

docker exec headscale hs_manage --listusers

列出所有已注册节点:

docker exec headscale hs_manage --listnodes

列出特定用户的节点:

docker exec headscale hs_manage --listnodes --user alice

按 ID 删除节点:

docker exec -it headscale hs_manage --deletenode 3
# 或跳过确认提示:
docker exec headscale hs_manage --deletenode 3 --yes

列出所有预授权密钥:

docker exec headscale hs_manage --listkeys

显示帮助:

docker exec headscale hs_manage --help

也可使用 docker exec headscale headscale <命令> 直接运行 Headscale 命令。运行 docker exec headscale headscale -h 或参阅 Headscale 文档 查看可用命令。

更新 Docker 镜像

要更新 Docker 镜像和容器,首先下载最新版本:

docker pull hwdsl2/headscale-server

如果 Docker 镜像已是最新版本,将显示:

Status: Image is up to date for hwdsl2/headscale-server:latest

否则将下载最新版本。按照快速开始中的说明删除并重新创建容器。数据保存在 headscale-data 卷中。

使用计数

此镜像使用公开的 GitHub Release 资源下载次数进行匿名聚合使用计数。计数是近似值,不代表唯一用户或活跃安装。镜像不会发送遥测负载,也不会使用私有收集器。仅当服务器启动且挂载了 /var/lib/headscale 卷后,才会以尽力而为方式计数;当该持久化安装首次运行不同镜像构建时,也会再次计数。要退出,请设置 HS_DISABLE_USAGE_COUNTS=1

技术细节

  • 基础镜像:alpine:3.23
  • Headscale:0.29.3
  • 数据目录:/var/lib/headscale(Docker 卷)
  • 配置文件:每次容器启动时从 vpn.env 重新生成;更新 vpn.env 并重启容器即可应用更改(无需重新创建容器)
  • 端口:8080/tcp(协调服务器),9090/tcp(Prometheus 指标,可选)
  • 支持平台:linux/amd64linux/arm64

授权协议

注: 预构建镜像中的软件组件(如 Headscale)遵循各自版权持有者所选择的相应许可证。对于任何预构建镜像的使用,镜像用户有责任确保其使用符合镜像中所包含的所有软件的相关许可证。

Copyright (C) 2026 Lin Song
本作品依据 MIT 许可证授权。

Headscale 的版权归 Juan Font 所有(2020 年),遵循 BSD 3-Clause 许可证

Tailscale® 是 Tailscale Inc. 的注册商标。本项目与 Tailscale Inc. 无关联,亦未获其背书。