在 VPS 上部署自建 Tailscale DERP 节点(Docker Compose)
Table of Contents
- 0. 适用环境与整体思路
- 1. 安装 Docker(含 Compose)
- 2. 安装并登录 Tailscale(宿主机)
- 3. 防火墙与安全组端口放行
- 4. 目录规划与 Docker Compose
- 5. 启动容器与基础校验
- 6. 在 Tailscale Admin Console 中配置 derpMap
- 6.1 单节点示例
- 6.2 双节点示例(新旧两台 VPS)
- 7. 无法使用 80/TCP 时:切换到 manual 证书模式
- 7.1 准备证书
- 7.2 修改 Docker Compose
- 8. 常见问题与排查思路
- 9. 迁移与备份
- 9.1 备份身份与 ACME 缓存
- 9.2 迁移到新机器
- 10. 多节点模板(双节点示例)
- 11. 权限与安全建议
这篇文章是给未来的自己看的,也给需要自建 Tailscale DERP 的人做一个可复制的参考。
目标很简单:
在一台小型 VPS 上,用 Docker Compose 跑一个 derper 容器,支持:
- Let’s Encrypt 自动签证书(80/443 开放时)
- 或手动证书(80 被机房拦截时)
- 在 Tailscale Admin Console 里通过
derpMap管理单节点/多节点
0. 适用环境与整体思路
系统要求
- Ubuntu 22.04+ 或 Debian 12+
- 1C / 1G 也能跑(低负载场景足够)
依赖条件
- 一台有公网 IPv4 的 VPS(建议开放 80/TCP、443/TCP、3478/UDP)
- 一个域名,例如:
derp.example.com,A 记录指向该 VPS - 一个已创建的 Tailscale Tailnet 账号
root或可sudo的账号
推荐方案
- 优先使用:Docker Compose +
letsencrypt自动证书 - 若 80/TCP 无法使用,再切换到 manual + 自备证书
如果要跑多个 DERP 节点,建议为每台机器准备独立子域名,例如:
derp.example.com→ Region hk1derphk.example.com→ Region hk2
1. 安装 Docker(含 Compose)
# 更新系统(可选)
sudo apt update && sudo apt -y upgrade
# 安装 Docker
sudo apt -y install docker.io
# 安装 docker compose 插件(Ubuntu 22.04+)
sudo apt -y install docker-compose-plugin
# 设置开机自启并立即启动
sudo systemctl enable --now docker
验证:
docker --version
docker compose version
2. 安装并登录 Tailscale(宿主机)
derper 如果启用 -verify-clients,需要访问宿主机的 tailscaled.sock,
因此宿主机必须运行 tailscaled 并加入你的 Tailnet。
curl -fsSL https://tailscale.com/install.sh | sh
sudo systemctl enable --now tailscaled
sudo tailscale up --ssh=false # 按提示在浏览器登录
检查状态:
systemctl is-active tailscaled && tailscale status | head -n 5
3. 防火墙与安全组端口放行
需要同时在云厂商“安全组”和系统防火墙(如 UFW)中放行:
80/TCP(Let’s Encrypt HTTP-01;如果后面只用 manual,可不开放)443/TCP(DERP TLS)3478/UDP(STUN)
示例(UFW):
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 3478/udp
sudo ufw enable
4. 目录规划与 Docker Compose
创建持久化目录和 compose 目录:
# 身份密钥 & ACME 缓存
sudo mkdir -p /opt/derper-data
# compose 项目
sudo mkdir -p /opt/derper && cd /opt/derper
新建 /opt/derper/docker-compose.yml(记得替换域名):
services:
derper:
image: fredliang/derper:latest
container_name: derper
restart: unless-stopped
ports:
- "80:80/tcp" # Let's Encrypt HTTP-01
- "443:443/tcp" # DERP TLS
- "3478:3478/udp" # STUN
environment:
DERP_DOMAIN: "derp.example.com" # ← 改成你的域名
DERP_ADDR: ":443"
DERP_HTTP_PORT: "80"
DERP_CERTMODE: "letsencrypt" # 若 80/TCP 无法用,后面改成 manual
DERP_STUN: "true"
DERP_VERIFY_CLIENTS: "true"
volumes:
- /opt/derper-data:/var/lib/derper
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
/var/lib/derper需要持久化,里面包含:
derper.key(DERP 身份私钥)- ACME 缓存和证书 这样容器重建不会频繁重新签证书,也保持 DERP 身份稳定。
5. 启动容器与基础校验
启动:
cd /opt/derper
docker compose up -d
检查端口监听情况:
# 80 / 443
ss -lntup | egrep ':80|:443' || true
# 3478
ss -lnup | egrep ':3478' || true
查看日志:
docker compose logs --tail=120
# 预期能看到类似 “serving on :443 with TLS” 的输出
验证 TLS 证书是否正常(Issuer 是否为 Let’s Encrypt,CN/SAN 是否包含你的域名):
openssl s_client -connect derp.example.com:443 -servername derp.example.com -brief </dev/null
以上都正常,说明 DERP 服务端基本可用了。
6. 在 Tailscale Admin Console 中配置 derpMap
进入 Admin Console → Access Controls,在 ACL JSON 中添加 derpMap 字段。
控制台支持带注释 JSON(
jsonc),如果提示语法错误,可以先去掉注释再保存。
6.1 单节点示例
"derpMap": {
"OmitDefaultRegions": false,
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "hk1",
"RegionName": "derp_1c1g",
"Nodes": [
{
"Name": "1",
"RegionID": 901,
"HostName": "derp.example.com"
}
]
}
}
}
6.2 双节点示例(新旧两台 VPS)
"derpMap": {
"OmitDefaultRegions": false,
"Regions": {
"901": {
"RegionID": 901,
"RegionCode": "hk1",
"RegionName": "derp_1c1g",
"Nodes": [
{ "Name": "1", "RegionID": 901, "HostName": "derp.example.com" }
]
},
"902": {
"RegionID": 902,
"RegionCode": "hk2",
"RegionName": "derp_2c4g",
"Nodes": [
{ "Name": "1", "RegionID": 902, "HostName": "derphk.example.com" }
]
}
}
}
保存之后,一般 1–3 分钟内会下发到客户端。
客户端验证(任意一个节点):
tailscale netcheck
# 预期能看到 hk1 / hk2 的 Region,且有延迟(UDP=true 更好)
7. 无法使用 80/TCP 时:切换到 manual 证书模式
部分机房对 80/TCP 有限制,导致 Let’s Encrypt HTTP-01 失败。
这种情况下可以切换到 manual 模式,自行管理证书。
7.1 准备证书
准备好域名证书和私钥(CN/SAN 包含 derp.example.com):
derp.example.com.crtderp.example.com.key
放到宿主机 /usr/local/cert:
sudo mkdir -p /usr/local/cert
sudo cp derp.example.com.crt derp.example.com.key /usr/local/cert/
sudo chmod 700 /usr/local/cert
sudo chmod 600 /usr/local/cert/*
7.2 修改 Docker Compose
在 docker-compose.yml 中:
environment:
DERP_CERTMODE: "manual"
DERP_DOMAIN: "derp.example.com"
DERP_ADDR: ":443"
DERP_STUN: "true"
DERP_VERIFY_CLIENTS: "true"
volumes:
- /opt/derper-data:/var/lib/derper
- /usr/local/cert:/cert # ← 新增
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock
manual模式下,镜像默认从/cert读取证书,一般不需要额外设置DERP_CERTDIR。 这时可以不开放 80/TCP,但 443/TCP 和 3478/UDP 必须可达。
重启并再次验证:
docker compose up -d
docker compose logs --tail=120
openssl s_client -connect derp.example.com:443 -servername derp.example.com -brief </dev/null
8. 常见问题与排查思路
1)443 端口占用
日志中出现 bind: address already in use:
ss -lntup | egrep ':443'
# 找到占用进程,停止后再启动 derper 容器
2)tailscale netcheck 看不到自建 Region
- 检查 Admin Console 中
derpMap的 JSON 是否保存成功、无语法错误; - 等待 1–3 分钟或在客户端执行
tailscale up --reset再登录; - 确认客户端网络能访问 DERP 域名的 443 端口。
3)UDP: false
- 说明客户端所在网络的 UDP 打洞能力较差;
- DERP 仍然可以工作,只是部分连接会走 TCP;
- 如果能控制网络环境,尽量保证客户端网络出站UDP可用。
4)Let’s Encrypt 申请失败
在日志中看到 acme/autocert 相关错误,或关于 HostWhitelist 的警告时:
- 检查域名解析是否正确指向当前 VPS;
- 检查 80/TCP 是否可从外网访问;
- 确认
DERP_DOMAIN与访问时的域名 / SNI 一致; - 如果机房不放行 80/TCP,直接切
manual模式即可。
5)-verify-clients 不生效
- 宿主机必须运行
tailscaled; - Compose 中需要挂载:
- /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock; - 可以用
tailscale status确认宿主机已成功加入 Tailnet。
6)频繁重建容器触发 LE 频率限制
- 确保
/var/lib/derper已挂载到宿主机:- /opt/derper-data:/var/lib/derper - 尽量不要在测试阶段频繁清空该目录。
9. 迁移与备份
9.1 备份身份与 ACME 缓存
sudo tar -C /opt -czf derper-data-backup.tgz derper-data
9.2 迁移到新机器
- 在新机器上按前文步骤安装 Docker、Tailscale、防火墙规则;
- 将旧机器的
/opt/derper-data拷贝到新机器同一路径; - 把域名 A 记录切换到新 IP;
- 按前文步骤启动 compose 并验证。
10. 多节点模板(双节点示例)
假设:
- 新 VPS(hk1):
derp.example.com - 旧 VPS(hk2):
derphk.example.com
两台机器可以使用相同的 docker-compose.yml 模板,只需要:
- 修改
DERP_DOMAIN为各自的域名; - 其余目录结构保持一致方便管理;
在 ACL 中使用前文的双节点 derpMap 配置,保存后,客户端执行:
tailscale netcheck
预期能看到 hk1 / hk2 的 Region 以及对应延迟。 连通性可以用:
tailscale ping <任意节点的 100.x IP>
11. 权限与安全建议
-
持久化目录中包含私钥和证书,建议最小权限:
sudo chown -R root:root /opt/derper-data /usr/local/cert sudo chmod 700 /opt/derper-data /usr/local/cert sudo find /usr/local/cert -type f -exec chmod 600 {} \; -
有需要的话,可以在宿主机额外部署:
fail2ban(简单暴力防护)logrotate(管理日志体积)
日常排查优先看两处:
docker compose logs- 客户端的
tailscale netcheck
这篇文章的目的,是给自己留一份“从零到可用”的 DERP 部署手册。
后面如果需要扩容更多 Region,就按同样的模板复制一份 compose、换域名、在 derpMap 里加 Region 即可。