上一篇 下一篇 分享链接 返回 返回顶部

用 Docker 部署 Cloudflare Tunnel:内网服务免公网 IP 访问配置指南

发布人:慈云数据-客服中心 发布时间:5小时前 阅读量:3

Cloudflare Docker部署教程|附配置文件

在日常的个人服务器、NAS、家庭实验室或中小型项目部署中,我们经常会遇到一个问题:本地服务已经通过 Docker 跑起来了,但如何安全、稳定、低成本地让外网访问?传统方案通常需要公网 IP、端口转发、反向代理、HTTPS 证书配置等步骤,对新手并不友好。

Cloudflare 提供的 Cloudflare Tunnel 可以很好地解决这个问题。它允许我们通过一个运行在本地服务器上的 cloudflared 客户端,主动与 Cloudflare 建立加密隧道,从而将内网 Docker 服务安全地暴露到公网。整个过程不需要公网 IP,也不需要在路由器上开放端口。

本文将以 Docker 方式部署 Cloudflare Tunnel,并附上完整配置文件示例,帮助你快速搭建一个可长期运行的 Cloudflare 访问方案。


一、什么是 Cloudflare Tunnel?

Cloudflare Tunnel 原名 Argo Tunnel,是 Cloudflare Zero Trust 产品中的一项功能。它的核心作用是:让你的本地服务通过一条安全隧道连接到 Cloudflare 网络,然后用户通过绑定的域名访问这些服务。

简单来说,传统访问方式是:

用户 -> 公网 IP -> 路由器端口转发 -> 服务器 -> Docker 服务

而使用 Cloudflare Tunnel 后变成:

用户 -> Cloudflare -> Cloudflare Tunnel -> 本地服务器 -> Docker 服务

这样做有几个明显优势:

  1. 无需公网 IP 即使你的服务器在家庭宽带、内网、NAT 后面,也可以通过域名访问。

  2. 无需开放端口 不需要在路由器、防火墙上开放 80、443 或其他业务端口,降低被扫描和攻击的风险。

  3. 自动 HTTPS 访问域名时由 Cloudflare 提供 HTTPS 证书,不需要你手动申请和续期证书。

  4. 适合 Docker 服务 很多自托管服务如 Home Assistant、Jellyfin、Vaultwarden、Nextcloud、Alist、Uptime Kuma 等,都可以通过 Tunnel 对外提供访问。

  5. 可结合 Zero Trust 权限控制 可以为服务增加登录验证、邮箱白名单、身份认证等安全策略。


二、准备工作

在开始部署之前,你需要准备以下内容:

1. 一个 Cloudflare 账号

如果还没有账号,可以前往 Cloudflare 官网注册:

https://www.cloudflare.com/

2. 一个托管到 Cloudflare 的域名

你需要有一个域名,并且该域名的 DNS 已经托管到 Cloudflare。

例如:

example.com

如果你的域名不在 Cloudflare,需要到域名注册商后台修改 DNS 服务器,将其指向 Cloudflare 提供的两个 NS 地址。

3. 一台安装了 Docker 的服务器

可以是:

  • 云服务器
  • 家庭服务器
  • NAS
  • 软路由
  • Linux 主机
  • 树莓派

本文以 Linux 服务器为例,要求已经安装:

docker
docker compose

查看 Docker 是否正常:

docker version
docker compose version

如果没有安装 Docker,可以使用以下命令快速安装:

curl -fsSL https://get.docker.com | bash

安装完成后,将当前用户加入 Docker 用户组:

sudo usermod -aG docker $USER

然后重新登录终端。


三、部署方式说明

使用 Docker 部署 Cloudflare Tunnel 通常有两种方式:

方式一:Token 模式

这是最简单的方式。你在 Cloudflare Zero Trust 后台创建 Tunnel 后,会得到一串 token,然后 Docker 容器通过 token 启动。

优点:

  • 简单
  • 配置少
  • 适合新手
  • 不需要本地维护证书文件

缺点:

  • 配置主要在 Cloudflare 后台完成
  • 不太适合完全文件化管理

方式二:配置文件模式

通过 config.yml 和凭证文件运行 Cloudflare Tunnel。

优点:

  • 配置清晰
  • 便于备份和迁移
  • 适合长期维护
  • 更适合多服务统一管理

缺点:

  • 初次配置步骤略多
  • 需要保存 tunnel 凭证文件

本文会重点介绍 Docker Compose + 配置文件模式,同时也会附上 Token 模式的快速部署方式。


四、在 Cloudflare 后台创建 Tunnel

首先登录 Cloudflare 控制台:

https://dash.cloudflare.com/

进入:

Zero Trust -> Networks -> Tunnels

点击:

Create a tunnel

选择:

Cloudflared

输入隧道名称,例如:

home-server

创建完成后,Cloudflare 会提供多种安装方式。你可以选择 Docker,然后会看到类似下面的命令:

docker run cloudflare/cloudflared:latest tunnel --no-autoupdate run --token 

如果你只想快速运行,可以直接使用这个 token。


五、Token 模式快速部署

如果你不想手动写配置文件,可以使用下面的 docker-compose.yml

目录结构

cloudflared/
└── docker-compose.yml

docker-compose.yml

version: "3.8"

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token YOUR_CLOUDFLARE_TUNNEL_TOKEN

将其中的:

YOUR_CLOUDFLARE_TUNNEL_TOKEN

替换为 Cloudflare 后台生成的 token。

启动容器:

docker compose up -d

查看日志:

docker logs -f cloudflared

如果看到类似内容:

Registered tunnel connection

说明隧道已经连接成功。

Token 模式下,你可以继续在 Cloudflare 后台添加 Public Hostname,例如:

app.example.com -> http://192.168.1.10:8080

或者:

alist.example.com -> http://alist:5244

如果服务和 cloudflared 在同一个 Docker 网络中,也可以通过容器名访问。


六、配置文件模式部署 Cloudflare Tunnel

下面进入更适合长期使用的配置文件模式。

1. 创建工作目录

在服务器上创建目录:

mkdir -p /opt/cloudflared
cd /opt/cloudflared

建议目录结构如下:

/opt/cloudflared
├── docker-compose.yml
├── config
│   ├── config.yml
│   └── credentials.json
└── data

其中:

  • docker-compose.yml:Docker Compose 启动文件
  • config.yml:cloudflared 配置文件
  • credentials.json:Tunnel 凭证文件
  • data:可选数据目录

七、获取 Cloudflare Tunnel 凭证文件

配置文件模式需要先在本地登录 Cloudflare,并创建 Tunnel 凭证。

你可以临时运行一个 cloudflared 容器进行登录。

1. 登录 Cloudflare

执行:

docker run --rm -it \
  -v /opt/cloudflared/config:/home/nonroot/.cloudflared \
  cloudflare/cloudflared:latest tunnel login

执行后,终端会输出一个登录链接。复制链接到浏览器打开,然后选择你的域名并授权。

授权完成后,会在本地目录生成一个证书文件,通常是:

cert.pem

目录示例:

/opt/cloudflared/config/cert.pem

2. 创建 Tunnel

假设我们创建一个名为 home-server 的 Tunnel:

docker run --rm -it \
  -v /opt/cloudflared/config:/home/nonroot/.cloudflared \
  cloudflare/cloudflared:latest tunnel create home-server

执行成功后,会生成一个 JSON 凭证文件,文件名通常是 Tunnel UUID,例如:

a1b2c3d4-xxxx-xxxx-xxxx-123456789abc.json

为了后续配置方便,可以将它复制或重命名为:

cp /opt/cloudflared/config/a1b2c3d4-xxxx-xxxx-xxxx-123456789abc.json \
   /opt/cloudflared/config/credentials.json

注意:credentials.json 是敏感文件,请不要上传到公开 Git 仓库。


八、创建 DNS 路由

创建好 Tunnel 后,需要将域名路由到这个 Tunnel。

例如,将:

app.example.com

绑定到 home-server Tunnel:

docker run --rm -it \
  -v /opt/cloudflared/config:/home/nonroot/.cloudflared \
  cloudflare/cloudflared:latest tunnel route dns home-server app.example.com

也可以为多个服务添加不同域名:

docker run --rm -it \
  -v /opt/cloudflared/config:/home/nonroot/.cloudflared \
  cloudflare/cloudflared:latest tunnel route dns home-server alist.example.com

docker run --rm -it \
  -v /opt/cloudflared/config:/home/nonroot/.cloudflared \
  cloudflare/cloudflared:latest tunnel route dns home-server uptime.example.com

Cloudflare 会自动在 DNS 中创建对应的 CNAME 记录。


九、编写 Cloudflared 配置文件

接下来创建配置文件:

nano /opt/cloudflared/config/config.yml

示例配置如下。

config.yml

tunnel: home-server
credentials-file: /etc/cloudflared/credentials.json

ingress:
  - hostname: app.example.com
    service: http://nginx-demo:80

  - hostname: alist.example.com
    service: http://alist:5244

  - hostname: uptime.example.com
    service: http://uptime-kuma:3001

  - hostname: nas.example.com
    service: http://192.168.1.100:5000

  - service: http_status:404

配置说明:

tunnel: home-server

这里填写 Tunnel 名称,也可以填写 Tunnel UUID。为了避免歧义,生产环境中更推荐填写 UUID。

credentials-file: /etc/cloudflared/credentials.json

这是容器内部的凭证路径。后面我们会通过 Docker Compose 将本地文件挂载到该路径。

ingress:

ingress 是访问规则列表。Cloudflare 会根据访问的 hostname 将请求转发到对应服务。

例如:

- hostname: app.example.com
  service: http://nginx-demo:80

表示访问:

https://app.example.com

会转发到 Docker 网络中的 nginx-demo 容器的 80 端口。

最后这一条很重要:

- service: http_status:404

它表示未匹配的请求返回 404。Cloudflare 官方要求 ingress 规则最后必须有一个兜底规则,否则配置可能无法正常生效。


十、编写 Docker Compose 配置文件

创建:

nano /opt/cloudflared/docker-compose.yml

docker-compose.yml

version: "3.8"

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --config /etc/cloudflared/config.yml run
    volumes:
      - ./config/config.yml:/etc/cloudflared/config.yml:ro
      - ./config/credentials.json:/etc/cloudflared/credentials.json:ro
    networks:
      - proxy

networks:
  proxy:
    external: true

这里使用了一个外部 Docker 网络 proxy。这样做的好处是:以后所有需要通过 Cloudflare Tunnel 暴露的服务,只要加入同一个 proxy 网络,就可以通过容器名访问。

创建 Docker 网络:

docker network create proxy

然后启动 Cloudflared:

cd /opt/cloudflared
docker compose up -d

查看运行状态:

docker ps

查看日志:

docker logs -f cloudflared

如果看到:

Registered tunnel connection

说明 Cloudflare Tunnel 已经成功运行。


十一、部署一个 Nginx 测试服务

为了验证 Tunnel 是否可用,我们部署一个 Nginx 测试容器。

创建目录:

mkdir -p /opt/nginx-demo
cd /opt/nginx-demo

编写 docker-compose.yml

version: "3.8"

services:
  nginx-demo:
    image: nginx:alpine
    container_name: nginx-demo
    restart: unless-stopped
    volumes:
      - ./html:/usr/share/nginx/html:ro
    networks:
      - proxy

networks:
  proxy:
    external: true

创建测试页面:

mkdir -p html
cat > html/index.html <


  
  Cloudflare Tunnel Test


  

Cloudflare Tunnel 部署成功

如果你看到这个页面,说明 Docker 服务已经通过 Cloudflare Tunnel 成功访问。

EOF

启动 Nginx:

docker compose up -d

确认配置文件中已经有:

- hostname: app.example.com
  service: http://nginx-demo:80

然后访问:

https://app.example.com

如果页面正常打开,就表示部署成功。


十二、暴露多个 Docker 服务

实际使用中,你可能会部署多个服务。例如:

  • Alist:文件列表
  • Uptime Kuma:监控页面
  • Vaultwarden:密码管理
  • Home Assistant:智能家居
  • Nextcloud:网盘

这些服务只要和 cloudflared 处于同一个 Docker 网络,就可以在 config.yml 中通过容器名转发。

示例:

ingress:
  - hostname: alist.example.com
    service: http://alist:5244

  - hostname: vault.example.com
    service: http://vaultwarden:80

  - hostname: kuma.example.com
    service: http://uptime-kuma:3001

  - hostname: home.example.com
    service: http://homeassistant:8123

  - service: http_status:404

对应服务的 Compose 文件中,需要加入:

networks:
  - proxy

并在底部声明:

networks:
  proxy:
    external: true

例如 Alist:

version: "3.8"

services:
  alist:
    image: xhofe/alist:latest
    container_name: alist
    restart: unless-stopped
    volumes:
      - ./data:/opt/alist/data
    networks:
      - proxy

networks:
  proxy:
    external: true

然后在 Cloudflare Tunnel 配置中写:

- hostname: alist.example.com
  service: http://alist:5244

十三、访问局域网 IP 服务

Cloudflare Tunnel 不仅可以转发 Docker 容器服务,也可以转发局域网内其他设备的服务。

比如你的 NAS 管理页面地址是:

http://192.168.1.100:5000

可以直接在 config.yml 中添加:

- hostname: nas.example.com
  service: http://192.168.1.100:5000

你的路由器后台是:

http://192.168.1.1

也可以写:

- hostname: router.example.com
  service: http://192.168.1.1

不过需要注意:路由器后台、NAS 管理页等敏感服务不建议直接公开访问,最好结合 Cloudflare Zero Trust Access 增加身份验证。


十四、建议开启 Cloudflare Zero Trust 访问控制

虽然 Cloudflare Tunnel 避免了开放端口,但并不代表所有服务都可以无保护地暴露到公网。尤其是管理后台、NAS、数据库面板、监控系统等服务,一定要添加访问控制。

可以在 Cloudflare Zero Trust 中配置 Access 应用:

路径:

Zero Trust -> Access -> Applications

新建 Self-hosted 应用,例如:

nas.example.com

然后设置策略:

Allow -> Emails -> yourname@example.com

这样访问 nas.example.com 时,会先进入 Cloudflare 登录验证页面,通过邮箱验证码、Google Workspace、GitHub、Azure AD 等方式认证后才能继续访问。

对于个人用户来说,最简单的方式是邮箱验证码:

只允许指定邮箱登录

这样可以明显提升安全性。


十五、常见问题排查

1. 容器启动后日志提示找不到 credentials 文件

检查 docker-compose.yml 中挂载路径是否正确:

volumes:
  - ./config/credentials.json:/etc/cloudflared/credentials.json:ro

同时确认宿主机文件存在:

ls -l /opt/cloudflared/config/credentials.json

2. 访问域名显示 404

检查 config.yml 中 hostname 是否写对:

- hostname: app.example.com
  service: http://nginx-demo:80

并确认最后有兜底规则:

- service: http_status:404

如果访问了没有配置的域名,返回 404 是正常现象。

3. 提示无法解析 Docker 容器名

如果 cloudflared 访问不到 nginx-demoalist 等容器名,通常是因为它们不在同一个 Docker 网络。

检查容器网络:

docker inspect cloudflared
docker inspect nginx-demo

确保它们都加入了同一个网络,例如:

proxy

4. Tunnel 已连接,但域名无法访问

检查以下几点:

  1. 域名是否已经托管到 Cloudflare;
  2. DNS 记录是否正确创建;
  3. Cloudflare Tunnel 是否处于 Healthy 状态;
  4. config.yml 中 hostname 是否与访问域名一致;
  5. 后端服务是否正常运行;
  6. 后端端口是否正确。

可以用容器内部测试网络:

docker exec -it cloudflared sh

进入容器后尝试:

wget -O- http://nginx-demo:80

如果能返回 HTML,说明 Cloudflared 到后端服务的网络是通的。

5. 修改配置后没有生效

修改 config.yml 后,需要重启 cloudflared 容器:

cd /opt/cloudflared
docker compose restart

或者:

docker restart cloudflared

查看日志确认是否加载成功:

docker logs -f cloudflared

十六、安全建议

为了长期稳定和安全运行,建议遵循以下原则:

1. 不要公开敏感后台

如路由器后台、NAS 管理、数据库管理工具、Portainer 等,不建议直接暴露到公网。如果必须访问,请务必加上 Cloudflare Access 身份认证。

2. credentials.json 不要泄露

credentials.json 相当于 Tunnel 凭证,泄露后可能导致他人连接你的隧道。建议设置合理文件权限:

chmod 600 /opt/cloudflared/config/credentials.json

3. 对外服务本身也要设置强密码

Cloudflare Tunnel 只是访问入口,不等于替你加固应用。应用本身仍应设置强密码、开启 2FA、及时更新版本。

4. 定期更新镜像

可以定期拉取最新版镜像:

docker compose pull
docker compose up -d

虽然 Cloudflare 官方命令常带有:

--no-autoupdate

但 Docker 场景下更推荐通过镜像更新统一管理版本。

5. 区分公开服务和私有服务

例如:

  • 博客、静态站点:可以公开
  • 监控、NAS、管理后台:建议 Access 保护
  • 数据库、Redis、SSH:不建议通过普通 Web Tunnel 直接暴露

十七、完整配置文件汇总

下面给出一套完整可用的配置示例,适合直接参考。

1. 目录结构

/opt/cloudflared
├── docker-compose.yml
└── config
    ├── config.yml
    └── credentials.json

2. docker-compose.yml

version: "3.8"

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --config /etc/cloudflared/config.yml run
    volumes:
      - ./config/config.yml:/etc/cloudflared/config.yml:ro
      - ./config/credentials.json:/etc/cloudflared/credentials.json:ro
    networks:
      - proxy

networks:
  proxy:
    external: true

3. config.yml

tunnel: home-server
credentials-file: /etc/cloudflared/credentials.json

ingress:
  - hostname: app.example.com
    service: http://nginx-demo:80

  - hostname: alist.example.com
    service: http://alist:5244

  - hostname: kuma.example.com
    service: http://uptime-kuma:3001

  - hostname: nas.example.com
    service: http://192.168.1.100:5000

  - service: http_status:404

4. Nginx 测试服务 docker-compose.yml

version: "3.8"

services:
  nginx-demo:
    image: nginx:alpine
    container_name: nginx-demo
    restart: unless-stopped
    volumes:
      - ./html:/usr/share/nginx/html:ro
    networks:
      - proxy

networks:
  proxy:
    external: true

十八、常用命令汇总

启动 Cloudflared

cd /opt/cloudflared
docker compose up -d

停止 Cloudflared

docker compose down

重启 Cloudflared

docker compose restart

查看日志

docker logs -f cloudflared

更新镜像

docker compose pull
docker compose up -d

查看 Docker 网络

docker network ls

创建 proxy 网络

docker network create proxy

十九、总结

通过 Docker 部署 Cloudflare Tunnel,可以非常方便地将本地服务、NAS 服务或 Docker 应用安全地发布到公网。相比传统端口转发方式,它最大的优势是不需要公网 IP、不需要开放路由器端口,并且可以直接使用 Cloudflare 提供的 HTTPS、DNS 和 Zero Trust 安全能力。

如果你只是想快速跑起来,可以使用 Token 模式;如果你希望长期维护、配置可控、方便备份,推荐使用本文介绍的配置文件模式。

最终推荐的部署思路是:

Cloudflare 域名
    ↓
Cloudflare Tunnel
    ↓
cloudflared Docker 容器
    ↓
Docker proxy 网络
    ↓
各类自托管服务

对于个人服务器、家庭 NAS、内网穿透、自托管应用来说,Cloudflare Tunnel 是一个非常实用的方案。配合 Docker Compose,可以做到部署简单、迁移方便、维护成本低,非常适合作为长期使用的反向代理与安全访问入口。

目录结构
全文