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

不用公网 IP,也能用 Docker 跑通 Cloudflare Tunnel 教程

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

Cloudflare Docker部署教程|零基础可学

在日常建站、内网穿透、家庭服务器、NAS 服务暴露、Webhook 回调测试等场景中,我们经常会遇到一个问题:本地服务已经跑起来了,但外网无法访问。传统做法可能需要公网 IP、路由器端口映射、DDNS、反向代理、SSL 证书配置等,对新手并不友好。

Cloudflare 提供的 Cloudflare Tunnel 可以很好地解决这个问题。它可以让你的本地服务通过 Cloudflare 的网络安全地暴露到公网,而无需公网 IP,也不需要在路由器上开放端口。配合 Docker 部署后,整个过程更加简单、可维护,也方便迁移。

本文将以零基础视角,详细讲解如何使用 Docker 部署 Cloudflare Tunnel,让你可以把本地网站、NAS、面板服务等通过自己的域名安全访问。


一、Cloudflare Docker部署适合什么场景?

在开始之前,我们先明确一下本文要实现的目标。

假设你有一台服务器、家用电脑、NAS 或者树莓派,上面运行着一个本地服务,例如:

http://localhost:8080

或者局域网中的服务:

http://192.168.1.100:8080

你希望通过类似下面的域名访问它:

https://app.example.com

如果使用 Cloudflare Tunnel,就可以做到:

  • 不需要公网 IP;
  • 不需要路由器端口转发;
  • 不需要手动申请 SSL 证书;
  • 可以隐藏真实服务器 IP;
  • 可以通过 Cloudflare 提供 HTTPS;
  • Docker 部署简单,后期维护方便;
  • 支持多个子域名转发到不同本地服务。

因此,Cloudflare Docker 部署非常适合以下用户:

  1. 家庭 NAS 用户;
  2. Home Assistant 用户;
  3. 自建博客用户;
  4. 本地开发测试用户;
  5. 需要公网 Webhook 回调的开发者;
  6. 不想开放服务器端口的个人站长;
  7. 想提升服务安全性的运维人员。

二、Cloudflare Tunnel是什么?

Cloudflare Tunnel 原名 Argo Tunnel,现在通常称为 Cloudflare Tunnel。它的核心组件是一个名为 cloudflared 的客户端程序。

它的工作方式可以简单理解为:

本地服务 → cloudflared 容器 → Cloudflare 网络 → 用户浏览器

传统暴露服务的方式是:

用户浏览器 → 公网 IP → 服务器开放端口 → 本地服务

而 Cloudflare Tunnel 的方式是:

本地服务主动连接 Cloudflare → Cloudflare 再把请求转发回来

这意味着你的服务器不需要开放入站端口,因为连接是由本地 cloudflared 主动发起到 Cloudflare 的。

这样做有几个明显好处:

  • 服务器真实 IP 不容易暴露;
  • 无需配置复杂的防火墙入站规则;
  • 没有公网 IP 的家庭宽带也能使用;
  • Cloudflare 可以帮你处理 HTTPS;
  • 结合 Cloudflare Access 还可以做访问认证。

三、部署前准备工作

在正式部署之前,你需要准备以下内容。

1. 一个 Cloudflare 账号

你需要先注册 Cloudflare 账号。

官网地址:

https://www.cloudflare.com/

注册过程比较简单,使用邮箱即可完成。


2. 一个已经托管到 Cloudflare 的域名

Cloudflare Tunnel 通常需要配合域名使用。你需要有一个域名,并且已经将域名的 DNS 托管到 Cloudflare。

简单来说,你需要完成这几件事:

  1. 购买一个域名;
  2. 登录 Cloudflare;
  3. 添加该域名;
  4. 根据 Cloudflare 提示,到域名注册商处修改 Nameserver;
  5. 等待 Cloudflare 显示域名状态为 Active。

例如你的域名是:

example.com

后续我们可以创建子域名:

app.example.com
nas.example.com
home.example.com

分别指向不同的本地服务。


3. 一台可以运行 Docker 的机器

你需要有一台已经安装 Docker 的设备,例如:

  • Linux 服务器;
  • Ubuntu / Debian 主机;
  • 群晖 NAS;
  • unRAID;
  • OpenWrt;
  • 树莓派;
  • Windows Docker Desktop;
  • macOS Docker Desktop。

本文主要以 Linux 环境为例讲解。

你可以通过下面命令检查 Docker 是否安装成功:

docker -v

如果能看到类似输出,说明 Docker 已安装:

Docker version 26.1.4, build 5650f9b

同时建议安装 Docker Compose:

docker compose version

如果能正常显示版本号,说明可以使用 Compose 部署。


四、Cloudflare Tunnel部署方式说明

Cloudflare Tunnel 常见部署方式有两种:

方式一:通过 Token 快速部署

这种方式最简单,也是新手最推荐的方式。

优点:

  • 不需要手动创建配置文件;
  • 不需要管理证书文件;
  • 直接复制 Cloudflare 提供的 Token;
  • Docker 一行命令即可运行。

缺点:

  • 配置主要在 Cloudflare 控制台中管理;
  • 对于喜欢本地配置文件的用户来说不够直观。

方式二:通过配置文件部署

这种方式更适合进阶用户。

优点:

  • 所有规则都可以写在本地 YAML 文件中;
  • 适合 Git 管理;
  • 灵活性更强。

缺点:

  • 初次配置相对复杂;
  • 需要登录授权并保存凭据;
  • 对新手不如 Token 方式友好。

本文重点讲解 方式一:Token 快速部署,因为它最适合零基础用户。


五、创建 Cloudflare Tunnel

1. 登录 Cloudflare 控制台

打开 Cloudflare 后台:

https://dash.cloudflare.com/

登录你的账号。


2. 进入 Zero Trust 控制台

在左侧菜单或首页中找到:

Zero Trust

首次进入时,Cloudflare 可能会让你创建团队名称。按照提示创建即可。

例如团队名称可以填写:

myhome

创建完成后进入 Zero Trust 控制台。


3. 创建 Tunnel

在 Zero Trust 后台中,依次进入:

Networks → Tunnels

然后点击:

Create a tunnel

接着选择:

Cloudflared

然后点击下一步。


4. 填写 Tunnel 名称

你可以给 Tunnel 起一个容易识别的名字,例如:

home-server

或者:

nas-tunnel

名称仅用于后台识别,不影响访问域名。

填写后点击保存。


5. 选择 Docker 部署方式

Cloudflare 会要求你选择运行环境,例如:

  • Docker;
  • Linux;
  • Windows;
  • macOS;
  • Kubernetes。

这里选择:

Docker

然后 Cloudflare 会生成一段类似下面的 Docker 命令:

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

其中 --token 后面的长字符串就是你的 Tunnel Token。

注意:Token 相当于这个隧道的身份凭据,不要公开到网上,也不要提交到公开仓库。


六、使用 Docker Run 快速部署

如果你只是想快速运行,可以直接使用 Cloudflare 提供的命令。

示例:

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

参数解释如下:

参数 说明
-d 后台运行容器
--name cloudflared 容器名称
--restart unless-stopped 容器异常退出后自动重启
cloudflare/cloudflared:latest 使用官方 cloudflared 镜像
tunnel run 运行 Tunnel
--token 使用 Cloudflare 提供的 Token 登录

运行后可以查看容器状态:

docker ps

如果看到 cloudflared 容器正在运行,说明第一步成功。

查看日志:

docker logs -f cloudflared

如果日志中出现类似内容:

Registered tunnel connection

说明 Tunnel 已经成功连接到 Cloudflare。


七、使用 Docker Compose部署Cloudflare Tunnel

虽然 docker run 很方便,但从长期维护角度来看,更推荐使用 Docker Compose。

1. 创建项目目录

例如:

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

2. 创建 docker-compose.yml

使用编辑器创建文件:

nano docker-compose.yml

写入以下内容:

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

如果你使用的是较老版本 Docker Compose,也可以加上:

version: "3.8"

完整示例:

version: "3.8"

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

3. 启动容器

docker-compose.yml 所在目录执行:

docker compose up -d

查看运行状态:

docker compose ps

查看日志:

docker compose logs -f

如果日志中不断显示连接成功,说明 Tunnel 正常工作。


八、配置公网域名访问本地服务

Tunnel 创建好了,只是建立了 Cloudflare 与本地机器之间的连接。接下来需要配置访问规则,也就是告诉 Cloudflare:

当用户访问哪个域名时,要转发到本地哪个服务。

示例场景

假设你的本地有一个 Web 服务运行在:

http://localhost:8080

你希望通过下面的域名访问:

https://app.example.com

配置步骤

进入 Cloudflare Zero Trust 后台:

Networks → Tunnels

找到刚才创建的 Tunnel,点击进入配置。

找到:

Public Hostname

点击:

Add a public hostname

然后填写:

配置项 示例
Subdomain app
Domain example.com
Path 留空
Type HTTP
URL localhost:8080

保存后,Cloudflare 会自动帮你创建对应 DNS 记录。

几分钟后访问:

https://app.example.com

如果你的本地服务正常运行,就可以看到页面。


九、Docker容器之间如何互通?

很多新手会遇到一个问题:

我的业务服务也是 Docker 容器,Cloudflared 容器里访问 localhost:8080 为什么不通?

这是因为在 Docker 中,每个容器都有自己的网络命名空间。对于 cloudflared 容器来说:

localhost

指的是 cloudflared 容器自己,而不是宿主机,也不是其他容器。

因此,如果你要让 Cloudflared 访问另一个 Docker 容器,推荐把它们放到同一个 Docker 网络中,然后通过容器名访问。


示例:同一个 Compose 中部署 Web 服务和 Cloudflared

假设你有一个 Nginx 服务,需要通过 Cloudflare Tunnel 暴露出去:

version: "3.8"

services:
  web:
    image: nginx:latest
    container_name: my-nginx
    restart: unless-stopped

  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token 你的Token

然后在 Cloudflare 后台 Public Hostname 中填写:

http://web:80

注意这里不是:

http://localhost:80

而是使用服务名:

web

因为在同一个 Docker Compose 网络中,服务之间可以通过服务名互相访问。


示例:Cloudflared访问宿主机服务

如果你的服务运行在宿主机上,例如:

http://127.0.0.1:8080

那么在容器里直接访问 localhost:8080 通常是不通的。

在 Linux 上,你可以让容器使用 host 网络模式:

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    network_mode: host
    command: tunnel --no-autoupdate run --token 你的Token

然后 Public Hostname 中可以填写:

http://localhost:8080

不过需要注意,network_mode: host 在 Linux 上常用,在 Docker Desktop 的 macOS 和 Windows 环境中表现可能不同。

另一种方式是使用宿主机网关地址,例如:

http://host.docker.internal:8080

在部分 Linux 版本 Docker 中,你可能需要在 Compose 中加入:

extra_hosts:
  - "host.docker.internal:host-gateway"

示例:

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    extra_hosts:
      - "host.docker.internal:host-gateway"
    command: tunnel --no-autoupdate run --token 你的Token

然后 Cloudflare 后台填写:

http://host.docker.internal:8080

十、同时暴露多个本地服务

Cloudflare Tunnel 可以同时转发多个域名到不同服务。

例如:

公网域名 本地地址
blog.example.com http://wordpress:80
nas.example.com http://192.168.1.10:5000
home.example.com http://homeassistant:8123
panel.example.com http://localhost:9000

在 Cloudflare 后台中,为同一个 Tunnel 添加多个 Public Hostname 即可。

例如:

博客服务

Subdomain: blog
Domain: example.com
Type: HTTP
URL: wordpress:80

NAS 管理页面

Subdomain: nas
Domain: example.com
Type: HTTP
URL: 192.168.1.10:5000

Home Assistant

Subdomain: home
Domain: example.com
Type: HTTP
URL: homeassistant:8123

配置保存后,每个域名都会通过同一个 Tunnel 转发到对应服务。


十一、HTTPS和证书需要自己配置吗?

一般情况下不需要。

当你使用 Cloudflare Tunnel 并通过 Cloudflare 托管的域名访问时,外部用户访问的是:

https://app.example.com

Cloudflare 会负责浏览器到 Cloudflare 边缘节点之间的 HTTPS 证书。

而 Cloudflare 到本地服务之间,可以使用 HTTP,也可以使用 HTTPS。

如果你的本地服务本身没有 HTTPS,配置时选择:

Type: HTTP
URL: localhost:8080

即可。

如果本地服务已经启用 HTTPS,可以选择:

Type: HTTPS
URL: localhost:8443

如果本地服务使用自签名证书,可能还需要在 Cloudflare Tunnel 的服务设置中开启跳过 TLS 验证,或者改用 HTTP 内网通信。

对于新手来说,最简单的方式是:

公网 HTTPS,内网 HTTP

也就是:

用户浏览器 --HTTPS--> Cloudflare --Tunnel--> 本地 HTTP 服务

这样既简单,又能保证公网访问时是 HTTPS。


十二、Cloudflare Tunnel安全建议

虽然 Cloudflare Tunnel 很方便,但不要因为方便就忽视安全。尤其是当你暴露的是管理面板、NAS、路由器后台、数据库面板等敏感服务时,一定要做好访问控制。

1. 不要直接暴露高风险后台

例如以下服务不建议直接裸奔到公网:

  • NAS 管理后台;
  • Portainer;
  • 宝塔面板;
  • Proxmox;
  • OpenWrt;
  • Home Assistant;
  • 数据库管理工具;
  • Jenkins;
  • GitLab;
  • 内网监控面板。

如果确实需要访问,建议配合 Cloudflare Access 做登录验证。


2. 启用 Cloudflare Access

Cloudflare Access 可以在用户访问你的服务之前,先要求进行身份验证。

例如你可以设置:

  • 只有指定邮箱可以访问;
  • 只有 Google 登录用户可以访问;
  • 只有 GitHub 组织成员可以访问;
  • 访问前需要一次性验证码。

这样即使别人知道你的域名,也无法直接进入服务页面。

配置入口通常在:

Zero Trust → Access → Applications

你可以添加一个 Self-hosted 应用,将域名设置为:

nas.example.com

然后设置访问策略,例如只允许你的邮箱:

yourname@example.com

3. 服务本身仍然要设置密码

Cloudflare Access 是第一层防护,但服务本身也应该设置强密码。

不要使用:

admin/admin
root/123456
test/test

建议使用:

  • 长密码;
  • 随机密码;
  • 密码管理器;
  • 双因素认证。

4. 不要泄露 Tunnel Token

Docker Compose 文件中如果写了 Token,不要上传到公开 GitHub 仓库。

如果你想更安全,可以使用 .env 文件管理 Token。

示例:

创建 .env

TUNNEL_TOKEN=你的Token

docker-compose.yml 写成:

services:
  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token ${TUNNEL_TOKEN}

这样后续管理更清晰,也更容易避免误提交。


十三、常见问题排查

1. 容器启动后访问域名显示 502

常见原因:

  • 本地服务没有启动;
  • Public Hostname 的 URL 填错;
  • 容器网络不通;
  • localhost 填错了;
  • 服务端口不正确。

排查方法:

查看 cloudflared 日志:

docker logs -f cloudflared

如果服务也是容器,确认它和 cloudflared 是否在同一个 Docker 网络中。


2. 日志显示连接成功,但域名打不开

可以检查:

  1. 域名是否已经托管到 Cloudflare;
  2. Public Hostname 是否保存成功;
  3. DNS 记录是否自动创建;
  4. 本地服务地址是否能在服务器上访问;
  5. 防火墙是否阻止了本地服务端口;
  6. Cloudflare Zero Trust 中 Tunnel 是否显示 Healthy。

3. Docker容器中访问 localhost 不通

这是最常见问题。

请记住:

容器里的 localhost = 容器自己

如果目标服务也是容器,请使用服务名:

http://web:80

如果目标服务在宿主机,请尝试:

http://host.docker.internal:端口

或者 Linux 下使用:

network_mode: host

4. 如何更新 cloudflared 镜像?

如果你使用的是 Docker Compose,可以这样更新:

cd /opt/cloudflared
docker compose pull
docker compose up -d

清理旧镜像:

docker image prune

由于命令中使用了:

--no-autoupdate

所以容器内部不会自动更新,需要通过 Docker 镜像更新。


5. 可以不用域名吗?

Cloudflare Tunnel 更推荐配合你自己的域名使用。

虽然 cloudflared 有临时隧道功能,可以生成临时域名,但不适合长期服务,也不适合生产环境。

如果你想长期稳定使用,建议购买一个域名并托管到 Cloudflare。


十四、推荐的目录结构

如果你后续会部署多个服务,建议使用清晰的目录结构:

/opt/
├── cloudflared/
│   ├── docker-compose.yml
│   └── .env
├── nginx/
│   └── docker-compose.yml
├── wordpress/
│   └── docker-compose.yml
└── homeassistant/
    └── docker-compose.yml

也可以把 cloudflared 和业务服务放在同一个 Compose 项目中,便于网络互通。

对于零基础用户来说,建议先采用:

每个服务一个目录

等熟悉 Docker 网络后,再考虑统一编排。


十五、完整示例:部署一个Nginx并通过Cloudflare访问

下面给出一个完整示例,帮助你从零到一跑通。

1. 创建目录

mkdir -p /opt/demo-cloudflare
cd /opt/demo-cloudflare

2. 创建 docker-compose.yml

version: "3.8"

services:
  web:
    image: nginx:latest
    container_name: demo-nginx
    restart: unless-stopped

  cloudflared:
    image: cloudflare/cloudflared:latest
    container_name: cloudflared
    restart: unless-stopped
    command: tunnel --no-autoupdate run --token 你的Token

3. 启动服务

docker compose up -d

4. 配置 Public Hostname

在 Cloudflare Zero Trust 中添加:

Subdomain: demo
Domain: example.com
Type: HTTP
URL: web:80

5. 访问测试

打开浏览器访问:

https://demo.example.com

如果看到 Nginx 欢迎页面,说明部署成功。


十六、总结

通过本文,你应该已经掌握了使用 Docker 部署 Cloudflare Tunnel 的完整流程。

整体步骤可以概括为:

  1. 注册 Cloudflare 账号;
  2. 将域名托管到 Cloudflare;
  3. 安装 Docker 和 Docker Compose;
  4. 在 Zero Trust 中创建 Tunnel;
  5. 复制 Docker Token;
  6. 使用 Docker Compose 启动 cloudflared
  7. 添加 Public Hostname;
  8. 将域名转发到本地服务;
  9. 根据需要添加多个服务;
  10. 配合 Cloudflare Access 提升安全性。

对于零基础用户来说,最推荐的部署方案是:

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

Cloudflare Tunnel 最大的优势在于:不需要公网 IP、不需要端口映射、不需要手动配置 HTTPS,就能把本地服务安全地发布到公网

如果你只是想把一个本地网站、NAS 页面、Home Assistant、测试项目或个人服务开放给自己访问,那么 Cloudflare Tunnel + Docker 是非常值得学习和使用的方案。

目录结构
全文