侧边栏壁纸
博主头像
KoolMax 博主等级

行动起来,活在当下

  • 累计撰写 13 篇文章
  • 累计创建 3 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

使用docker-compose一键部署headscale、derper和webui

Administrator
2025-07-22 / 0 评论 / 0 点赞 / 3 阅读 / 0 字

之前在 sealos 上部署过 headscale、derper 和 webui,但是由于 sealos 的一些问题,导致 headscale 无法正常使用。最近申请的域名备案也成功通过了,所以这次我尝试使用 docker-compose 在阿里云上部署 headscale、derper 和 webui。

前提条件

  • 一台具有公网 IP 的服务器

  • 一个域名 (需要两个二级域名,一个用于 headscale 和 webui,一个用于 derper)

  • 域名证书 (可以使用acme.sh申请免费证书)

  • 占用以下端口

    • tcp 58080 (headscale server)

    • tcp 57070 (headscale webui)

    • tcp 56060 (headscale derp)

    • udp 3478 (headscale derp stun)

部署 headscale、derper 和 webui

首先,需要在服务器上安装 docker 和 docker-compose。参考

然后,我们需要在服务器上创建一个目录,用于存放相关文件,结构如下。

➜  headscale tree
.
├── docker-compose.yaml
├── dockerfiles
│   └── derp.Dockerfile
├── headscale
│   └── config
│       ├── config.yaml
│       └── derp.yaml
└──  nginx
    ├── derp.conf
    └── headscale.conf

docker-compose.yaml

compose 文件仅部署了 headscale、headscale-admin、derp、client,请按需进行修改。

注意

要提前配置好 config.yaml 和 derp.yaml,并放入 headscale/config 文件夹内,可以去headscale的代码仓下载 config-example.yaml 和 derp-example.yaml。内容可以参考配置文件部分

docker-compose.yamlyaml

# docker-compose.yaml
version: "3.9"
networks:
  private:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.200.0/24

services:
  server:
    image: headscale/headscale:latest-debug
    container_name: headscale-server
    networks:
      - private
    volumes:
      - ./headscale/config:/etc/headscale
      - ./headscale/data:/var/lib/headscale
      - ./headscale/run:/var/run/headscale
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    ports:
      - "58080:8080"
    command: serve
    restart: unless-stopped
    depends_on:
      - derp

  webui:
    image: goodieshq/headscale-admin:latest
    container_name: headscale-ui
    networks:
      - private
    environment:
      PORT: 7070
    ports:
      - "57070:7070"
    volumes:
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    restart: unless-stopped

  derp:
    build:
      context: ./dockerfiles
      dockerfile: derp.Dockerfile
    container_name: headscale-derp
    networks:
      - private
    environment:
      DERP_DOMAIN: hsderp.example.com
      DERP_ADDR: :6060
      DERP_CERT_MODE: letsencrypt
      DERP_VERIFY_CLIENTS: true
    ports:
      - "56060:6060" # derp port, TCP
      - "3478:3478/udp" # STUN port, UDP
    volumes:
      - ./tailscale:/var/run/tailscale
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
    restart: unless-stopped

  client:
    image: tailscale/tailscale:stable
    container_name: tailscale-client
    network_mode: "host"
    privileged: true
    environment:
      TS_EXTRA_ARGS: --netfilter-mode = off
    volumes:
      - ./tailscale:/var/run/tailscale
      - /usr/share/zoneinfo/Asia/Shanghai:/etc/localtime:ro
      - /var/lib:/var/lib
      - /dev/net/tun:/dev/net/tun
    cap_add:
      - net_admin
      - sys_module
    command: tailscaled
    restart: unless-stopped

derp.Dockerfile

因 derp 镜像更新不及时,所以需要手动构建,需将 derp.Dockerfile 放入 dockerfiles 文件夹内。

dockerfiles/derp.Dockerfiledockerfile

FROM golang:alpine AS builder

WORKDIR /app

# https://tailscale.com/kb/1118/custom-derp-servers/
RUN go env -w GOPROXY=https://goproxy.io,direct
RUN go install tailscale.com/cmd/derper@latest


FROM alpine:3.21

WORKDIR /app

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2
RUN apk add --no-cache ca-certificates iptables iproute2 ip6tables curl && \
    mkdir /app/certs

RUN apk add gcompat

ENV DERP_DOMAIN=your-hostname.com
ENV DERP_CERT_MODE=letsencrypt
ENV DERP_CERT_DIR=/app/certs
ENV DERP_ADDR=:443
ENV DERP_STUN=true
ENV DERP_STUN_PORT=3478
ENV DERP_HTTP_PORT=80
ENV DERP_VERIFY_CLIENTS=false
ENV DERP_VERIFY_CLIENT_URL=""
COPY --from=builder /go/bin/* /usr/local/bin/

CMD /usr/local/bin/derper --hostname=$DERP_DOMAIN \
    --certmode=$DERP_CERT_MODE \
    --certdir=$DERP_CERT_DIR \
    --a=$DERP_ADDR \
    --stun=$DERP_STUN \
    --stun-port=$DERP_STUN_PORT \
    --http-port=$DERP_HTTP_PORT \
    --verify-clients=$DERP_VERIFY_CLIENTS \
    --verify-client-url=$DERP_VERIFY_CLIENT_URL

使用 docker-compose 部署

在 headscale 目录下执行以下命令,即可部署 headscale、derp 和 webui。

sudo docker-compose up -d

配置文件

headscale/config/config.yamlyaml

...

server_url: https://hs.example.com
listen_addr: 0.0.0.0:8080
metrics_listen_addr: 0.0.0.0:9090
grpc_listen_addr: 0.0.0.0:50443

...

derp:

  ...

  urls: []
  paths:
    - /etc/headscale/derp.yaml

注意

这里只展示 headscale/config/config.yaml 的部分配置,其他配置请参考config-example.yaml

headscale/config/derp.yamlyaml

regions:
  999:
    regionid: 999
    regioncode: cnbj
    regionname: Aliyun Beijing
    nodes:
      - name: derp
        regionid: 999
        hostname: hsderp.example.com
        stunport: 3478
        stunonly: false
        derpport: 443

nginx 配置

在 nginx.conf 的 http 块中 include 以下配置文件以实现反向代理。

headscale.confnginx

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

    location ^~ / {
        proxy_pass http://127.0.0.1:58080;
        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 REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        add_header X-Cache $upstream_cache_status;
        add_header Strict-Transport-Security "max-age=31536000";
        add_header Cache-Control no-cache;
    }

    location ^~ /admin {
        proxy_pass http://127.0.0.1:57070;
        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 REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        add_header X-Cache $upstream_cache_status;
        add_header Strict-Transport-Security "max-age=31536000";
        add_header Cache-Control no-cache;
    }
}

server {
    listen 80;
    server_name hs.example.com;;
    return 301 https://$host$request_uri;
}

derp.confnginx

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

    location ^~ / {
        proxy_pass http://127.0.0.1:56060;
        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 REMOTE-HOST $remote_addr;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        add_header X-Cache $upstream_cache_status;
        add_header Strict-Transport-Security "max-age=31536000";
    }
}

server {
    listen 80;
    server_name hsderp.example.com;;
    return 301 https://$host$request_uri;
}

测试

在浏览器中打开https://hs.example.com/adminhttps://haderp.example.com 若均可看到相关页面,说明部署成功。

注意

因为开启了 DERP_VERIFY_CLIENTS,所以在所有服务部署成功后,需要手动把 tailscale-client 添加到 headscale 中,derper 才能正常使用。 使用以下命令进入 tailscale-client 容器,在 headscale admin 页面点击 deploy 然后复制对应的命令以连接 headscale。

sudo docker exec -it tailscale-client /bin/sh

admin

提示

这是我部署使用后的 headscale admin 页面,所以已经有设备和用户,刚部署好的所有数字应该都是 0。

derp

参考

0

评论区