← 返回教程
教程

ucloud dokploy cloudflare tunnel 安全访问配置总结

UCloud + Dokploy + Cloudflare Tunnel 安全访问配置

TL;DR

隐藏 UCloud 公网入口,所有流量只走 Cloudflare Tunnel,不再直接暴露服务器 IP。

用户
 └─ Cloudflare (HTTPS)
     └─ Cloudflare Tunnel
         └─ cloudflared 容器(--network host)
             └─ Traefik / Dokploy(HTTP localhost:80)
                 ├─ admin-xxx
                 ├─ api-xxx
                 └─ dokploy 后台

最终效果:


域名规划

域名用途
admin-xxx.your-domain.com前端 / 管理页面
api-xxx.your-domain.com后端 API
dokploy.your-domain.comDokploy 管理后台

步骤一:创建 Cloudflare Tunnel

路径:Zero Trust → Networks → Tunnels → Create Tunnel

Tunnel 名称:ucloud-1,运行环境选 Docker。

Cloudflare 生成的原始命令不够用,改用以下命令启动:

docker run -d \
  --name cloudflared \
  --restart unless-stopped \
  --network host \
  cloudflare/cloudflared:latest \
  tunnel --no-autoupdate run --token 你的完整token

--network host 必须加。 不加的话 localhost:80 指向的是 cloudflared 容器自己,而不是宿主机的 Traefik。

验证是否运行:

docker ps | grep cloudflared
docker logs -f cloudflared   # 看到 "Connection established" 即成功

步骤二:配置 Tunnel 路由

路径:Zero Trust → Networks → Tunnels → ucloud-1 → Public Hostnames

三个域名全部指向同一个目标:

域名目标
admin-xxx.your-domain.comhttp://localhost:80
api-xxx.your-domain.comhttp://localhost:80
dokploy.your-domain.comhttp://localhost:80

Traefik 会根据 Host 请求头自动路由,不需要填容器端口或公网 IP。


步骤三:修改 Cloudflare DNS

删除旧 A 记录,改为 CNAME 指向 Tunnel:

类型名称目标
Aadmin-xxxYOUR_SERVER_IP
CNAMEadmin-xxx<TunnelID>.cfargotunnel.com
CNAMEapi-xxx<TunnelID>.cfargotunnel.com
CNAMEdokploy<TunnelID>.cfargotunnel.com

CNAME 目标格式是 TunnelID.cfargotunnel.com(不是 tunnel 名称 ucloud-1)。

如果提示 DNS record operation failed: HTTP 400,说明旧 A 记录还存在,先删再手动建 CNAME。


步骤四:配置 Dokploy 域名

关键原则: Cloudflare 负责外部 HTTPS,Dokploy 内部关闭 HTTPS,Tunnel 走 HTTP。

若 Dokploy 开启 HTTPS,Traefik 会把 HTTP 请求 308 跳转到 HTTPS,导致 Tunnel 链路反复重定向。

admin-xxx

字段
Domainadmin-xxx.your-domain.com
Container Port80
HTTPS关闭
# 验证
curl -I -H "Host: admin-xxx.your-domain.com" http://127.0.0.1
# 期望:HTTP/1.1 200 OK

api-xxx

字段
Domainapi-xxx.your-domain.com
Container Port3000(填服务实际监听端口)
HTTPS关闭
# 根路由 404 不代表错误,测试真实接口路径
curl -i -H "Host: api-xxx.your-domain.com" http://127.0.0.1/真实接口路径

dokploy

字段
Domaindokploy.your-domain.com
Container Port3000(Dokploy 默认)
HTTPS关闭

步骤五:SSL/TLS 设置

Cloudflare 全局模式保持 Full strict(完整严格),不要改成 Flexible 或关闭。


⚠️ 警告:不要给 Dokploy 加 Cloudflare Access

不要给 dokploy.your-domain.com 配置 Cloudflare Access 保护。

CI/CD(GitHub Actions 等)部署时需要直接调用 Dokploy API,Cloudflare Access 会拦截所有自动化请求,导致部署全部失败。

Dokploy 本身有用户名 + 密码保护,只要服务器 80 / 443 对公网关闭,风险已经很低。


步骤六:关闭 UCloud 公网端口

确认三个域名均可正常访问后,在 UCloud 安全组删除以下规则:

协议端口来源操作
TCP800.0.0.0/0删除
TCP4430.0.0.0/0删除
TCP33890.0.0.0/0删除
ICMP0.0.0.0/0删除
TCP22你的公网 IP/32保留

SSH 加固(修改后 sudo systemctl restart ssh):

PasswordAuthentication no
PermitRootLogin no
PubkeyAuthentication yes

关闭密码登录前,必须先确认密钥登录可用,否则会把自己锁在服务器外。


常用检查命令

# Tunnel 状态
docker ps | grep cloudflared
docker logs -f cloudflared

# 本机路由测试
curl -I -H "Host: admin-xxx.your-domain.com" http://127.0.0.1
curl -I -H "Host: api-xxx.your-domain.com" http://127.0.0.1

# 外部访问测试
curl -I https://admin-xxx.your-domain.com
curl -I https://api-xxx.your-domain.com
curl -I https://dokploy.your-domain.com

# 服务器状态
sudo ss -lntp
docker ps
docker logs --tail=100 容器名

注意事项速查

#规则
1不要给任何域名加 Cloudflare Access(会拦截 CI/CD)
2Tunnel 路由统一指向 http://localhost:80
3Dokploy 应用内部 HTTPS 关闭
4Cloudflare 全局 SSL/TLS 保持 Full strict
5DNS 删除指向 UCloud IP 的 A 记录
6UCloud 安全组关闭 80 / 443
7cloudflared 容器保持运行,使用 --network host