下面分别给出 FRP 和 Rathole 的完整 Docker 部署方案。两者都支持 ARM64 与 x86_64 架构,适合“云服务器(公网) + 家用 NAS(内网)”的穿透场景。
方案一:FRP 部署方案
根据你提供的镜像列表和需求(客户端必须支持ARM64、安全优先、资源消耗低),以下是基于 FRP 的完整部署方案。
镜像选择
服务端(云服务器):snowdreamtech/frps:0.70.1-alpine
选择理由:Alpine 基础镜像体积远小于 Debian 版本(130MB vs 319MB),攻击面更小;0.70.1 是当前较新版本,修复了已知安全漏洞;snowdreamtech 系列镜像持续同步官方 Release,且明确提供 ARM64 构建。
客户端(NAS / ARM64设备):firfe/frpc:0.71.0-arm64
选择理由:列表中的 snowdreamtech/frpc:latest 同时包含 amd64 和 arm64 标签,但未固定具体版本号,不利于可复现部署;firfe/frpc:0.71.0-arm64 提供了明确的 arm64 专用标签,压缩后仅 9.73MB,资源占用极低。0.71.0 与 0.70.1 在协议层面完全兼容。
注意:官方
fatedier/frps和fatedier/frpc镜像确实支持多架构,但 Docker Hub 上的linux/arm64标签推送不稳定。使用 snowdreamtech / firfe 等经过验证的第三方构建是更可靠的选择。
配置文件准备
服务端 frps.toml(云服务器)
bindPort = 17000
auth.token = "请替换为至少32位随机字符串"
webServer.addr = "0.0.0.0"
webServer.port = 17500
webServer.user = "admin"
webServer.password = "请替换为强密码"
log.to = "console"
log.level = "warn"
Docker Compose 部署
- docker.io/snowdreamtech/frps:0.70.1-alpine
云服务器端 docker-compose.yml
services:
frps:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/snowdreamtech/frps:0.70.1-alpine
container_name: frps
restart: always
volumes:
- ./frps.toml:/etc/frp/frps.toml:ro
network_mode: "host"
command: ["-c", "/etc/frp/frps.toml"]
镜像地址来自 aityp 镜像站对 docker.io/snowdreamtech/frps:0.70.1-alpine 的同步地址。
NAS 端 docker-compose.yml
- docker.io/snowdreamtech/frpc:0.70.1-alpine
services:
frpc:
image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/snowdreamtech/frpc:0.70.1-alpine-linuxarm64
container_name: frpc
restart: unless-stopped
network_mode: host
entrypoint:
- /usr/bin/frpc
- tcp
- --proxy-name=my-frpc
- --server-addr=云服务器公网IP
- --server-port=17000
- --token=与服务端完全一致的Token
- --local-ip=127.0.0.1
- --local-port=5000
- --remote-port=18080
客户端镜像的 arm64 标签压缩后仅 9.73MB,非常适合低功耗 ARM NAS 长期运行。
如果 aityp 镜像站未收录
firfe/frpc:0.71.0-arm64,可改用snowdreamtech/frpc的 arm64 标签,或在 aityp 搜索页确认对应同步地址后替换。两者的客户端配置文件完全兼容。
部署步骤
1. 云服务器
云服务器安全组放行:
-
17000(FRP 控制端口)
-
18080(实际服务暴露端口,按需)
-
17500(管理面板,强烈建议限制来源 IP,或直接不放行)
将 frps.toml 和 docker-compose.yml 放入同一目录,执行:
docker compose up -d
2. 云服务器防火墙/安全组
放行以下端口:
| 端口 | 用途 | 建议 |
|---|---|---|
| 7000 | FRP 控制端口 | 可限制来源为 NAS 的公网出口 IP |
| 7500 | Web 管理面板 | 强烈建议限制来源 IP,或直接不对外暴露 |
| 8080 | 实际服务暴露端口 | 按需放行 |
3. NAS 端
将 frpc.toml 中的 serverAddr 改为云服务器公网 IP,然后执行:
docker compose up -d
4. 验证
在公网访问 云服务器IP:8080,应能打开 NAS 上对应服务(如 Web 管理界面)。
安全加固要点
- Token 强度:
auth.token务必使用 32 位以上随机字符串,避免被暴力破解。 - 管理面板来源限制:FRP 的 7500 端口仅做 Basic Auth,一旦暴露在公网存在被爆破风险。推荐做法是不在云服务器安全组中放行 7500,需要管理时通过 SSH 隧道访问,或使用
webServer.addr = "127.0.0.1"仅绑定本地。 - 镜像版本固定:不要使用
latest标签。本方案固定了0.70.1-alpine(服务端)和0.71.0-arm64(客户端),确保部署结果可复现,不会因镜像静默更新引入意外变更。 - 配置文件只读挂载:
docker-compose.yml中配置文件以:ro方式挂载,防止容器内进程意外修改配置。
方案二:Rathole 部署方案
Rathole 用 Rust 编写,资源占用比 FRP 更低,尤其适合在性能有限的 NAS 上长期运行。它的配置比 FRP 更简洁,服务端和客户端使用同一个二进制文件,只是传入的配置文件不同。
镜像选择
| 镜像 | 说明 |
|---|---|
rapiz1/rathole:latest | 官方镜像,已支持多架构(linux/amd64 + linux/arm64) |
7a6163/rathole | 第三方多架构镜像,支持 amd64、arm64、arm/v7、arm/v6 |
archef2000/rathole | 多架构镜像,支持环境变量方式配置,体积约 4.76MB(ARM64) |
推荐优先使用官方镜像 rapiz1/rathole,其多架构支持已由官方自动构建维护。
配置文件准备
Rathole 不使用 TOML 中的嵌套代理块,而是用 [server.services.xxx] 和 [client.services.xxx] 来定义每个穿透服务。
服务端配置 server.toml(放在云服务器上):
[server]
bind_addr = "0.0.0.0:2333" # 客户端连接端口
[server.services.nas-web] # 服务名称,两端必须一致
token = "your-strong-random-token-here"
bind_addr = "0.0.0.0:8080" # 在云服务器上暴露的端口
客户端配置 client.toml(放在 NAS 上):
[client]
remote_addr = "your-cloud-server-public-ip:2333"
[client.services.nas-web]
token = "your-strong-random-token-here"
local_addr = "127.0.0.1:5000" # NAS 上实际服务的地址
Rathole 的配置逻辑非常直观:服务端定义“对外暴露哪个端口”,客户端定义“转发本地的哪个服务”。
Docker Compose 部署
云服务器端 docker-compose.yml:
services:
rathole-server:
image: rapiz1/rathole:latest
container_name: rathole-server
restart: unless-stopped
volumes:
- ./server.toml:/app/config.toml:ro
ports:
- "2333:2333"
- "8080:8080"
command: ["/app/rathole", "/app/config.toml"]
NAS 端 docker-compose.yml:
services:
rathole-client:
image: rapiz1/rathole:latest
container_name: rathole-client
restart: unless-stopped
volumes:
- ./client.toml:/app/config.toml:ro
network_mode: "host"
command: ["/app/rathole", "client", "/app/config.toml"]
客户端必须使用 network_mode: "host",这样才能通过 127.0.0.1 访问 NAS 宿主机上的本地服务。服务端则通过 ports 显式暴露控制端口(2333)和实际服务端口(8080)。
部署步骤
- 云服务器:将
server.toml和docker-compose.yml放在同一目录,执行docker compose up -d。 - 云服务器防火墙/安全组:放行
2333(控制端口)和8080(服务暴露端口)。 - NAS:将
client.toml中的remote_addr改为云服务器公网 IP,执行docker compose up -d。 - 验证:在公网访问
云服务器IP:8080,应能打开 NAS 的 Web 服务。
两个方案的对比与选择建议
| 维度 | FRP | Rathole |
|---|---|---|
| 配置复杂度 | 功能丰富,配置项多,灵活但稍复杂 | 配置极简,学习成本低 |
| 资源占用 | Go 编写,内存占用中等 | Rust 编写,内存和二进制体积均更小 |
| 生态与文档 | 社区庞大,中文资料极多,镜像选择丰富 | 社区较小,但官方文档清晰 |
| 多服务穿透 | 通过多个 [[proxies]] 块实现 | 通过多个 [*.services.xxx] 块实现 |
| 管理面板 | 内置 Web 管理面板 | 无内置面板,日志查看即可 |
| 适合场景 | 需要管理面板、复杂路由规则、HTTP 头改写等高级功能 | 追求极致轻量,只需简单的 TCP 端口转发 |
选择建议:如果你的 NAS 性能够用,且希望有一个可视化管理面板和更丰富的功能生态,选 FRP。如果你的 NAS 是 ARM 架构的低功耗设备(如树莓派、ARM 版群晖),希望把资源占用压到最低,且只需要干净利落的端口转发,选 Rathole。
两个方案都建议在云服务器安全组中严格限制管理端口(FRP 的 7500)的访问来源,并为 Token 使用足够长的随机字符串。