用 Docker 一键部署 frps 服务端
之前写了篇 frp 内网穿透的教程,当时是直接把 frps 二进制文件丢服务器上用 systemd 管理的。后来寻思这玩意儿能不能用 Docker 跑,一来方便管理不怕环境搞乱,二来换服务器的时候 docker-compose up -d 一行命令就搞定了不用重新配。折腾了一下发现还真挺好使,搞了个精简镜像才不到 30M,干脆开个仓库记录一下。
仓库地址:https://github.com/Jerry-FaGe/frps-docker
先决条件
Docker
Docker Compose
一台有公网 IP 的服务器(云服务器就行)
为什么用 Docker 跑 frps
直接跑二进制文件有啥问题呢?倒也不是不行,就是有点烦:
- 环境依赖 —— 虽然 frps 本身是静态编译的没啥依赖,但你想改配置、看日志、管理进程,还是得手动搞 systemd service 文件
- 升级麻烦 —— 每次升级得手动下载、解压、替换文件、重启服务,搞不好还得回滚
- 多实例不方便 —— 如果你想跑多个 frps 实例(比如测试环境和生产环境),用 systemd 管理就比较痛苦
用 Docker 的话这些问题都不存在了。镜像自带配置,升级就改个版本号重新 build,多实例直接改个端口映射就行。
项目结构
整个项目就四个文件,非常简单:
1 | frps-docker/ |
Dockerfile 解析
1 | # 用 Alpine 做基础镜像,整个 build 完不到 30M |
几个要点:
- 基础镜像用的 Alpine,整个镜像 build 完才不到 30M,比用 Ubuntu 小太多了
FRP_VERSION改一下就能升级 frp 版本,不用手动下载- 换了阿里云镜像源,不然在国内服务器上
apk update能给你卡半天 - 配了时区为
Asia/Shanghai,日志时间戳就对了 - 下载完 frp 之后把客户端的文件(
frpc、frpc.toml)都删了,服务端用不上
docker-compose.yml
直接贴仓库里的配置:
1 | services: |
这里用了 network_mode: host,意思是容器直接使用宿主机的网络栈,不需要额外做端口映射。为啥用 host 模式呢?因为 frps 需要监听的端口是动态的——你的 frpc 客户端连什么端口,frps 就要开什么端口。如果用 bridge 模式的话,每加一个代理就得在 docker-compose 里加一行端口映射,贼麻烦。
当然 host 模式也有缺点,就是容器和宿主机共用网络命名空间,隔离性差一些。但对于 frps 这种场景来说完全够用了。
查看各字段解释
build: .—— 用当前目录的 Dockerfile 构建镜像image: frps—— 指定构建后的镜像名称,方便后续管理container_name: frps—— 容器名叫 frps,docker logs frps就能看日志privileged: true—— 特权模式,给容器更高的权限,避免一些网络相关的权限报错restart: always—— 容器挂了自动重启,docker-compose down才会停network_mode: host—— 直接用宿主机网络,不需要-p映射端口environment: TZ—— 设时区,跟 Dockerfile 里的保持一致volumes—— 把宿主机的frps.toml挂载到容器里的/frp/frps.toml
frps.toml 配置
1 | bindPort = 7000 # frpc 连接用的端口 |
auth.token 一定要改成强密码!别用 12345678 这种。同理 Dashboard 的密码也要改,不然被人扫到 Dashboard 就能看到你所有的代理配置。
使用方法
1 | git clone https://github.com/Jerry-FaGe/frps-docker.git |
先把 token 和密码改了!这是最重要的一步。
1 | vim frps.toml |
1 | docker-compose up -d |
看到类似这样的输出就说明成功了:
1 | [+] Building 12.5s (9/9) FINISHED |
1 | docker-compose logs -f |
看到 frps tcp listen success 就说明服务端启动成功了。
升级 frp 版本
只需要改 Dockerfile 里的 FRP_VERSION:
1 | ENV FRP_VERSION=0.61.1 # 改成你想要的版本 |
然后重新 build:
1 | docker-compose build --no-cache |
搞定。回滚也简单,把版本号改回去重新 build 就行。
跟客户端配合
服务端用 Docker 跑了之后,客户端(frpc)的配置跟之前一样不用变。参考之前写的那篇 frp 内网穿透从零搭建指南,把 serverAddr 改成你服务器的公网 IP 就行。
1 | serverAddr = "你的服务器公网IP" |
一些细节
部署过程中踩过的点
自动重启
restart: always 保证了容器异常退出后会自动重启,除非你手动 docker-compose down。服务器重启后容器也会自动拉起来,不用操心。
日志管理
frps 的日志直接输出到 stdout,用 docker-compose logs -f 就能实时查看。不加任何额外配置,Docker 自己会管理日志轮转。
配置文件热更新?
frps.toml 之后必须重启容器才能生效:docker-compose restart frps
特权模式
用了 privileged: true 是因为 frps 需要操作网络相关的系统调用。如果不用特权模式,某些情况下可能会报权限错误。当然如果你的环境不需要可以去掉这行。
总结
用 Docker 跑 frps 的好处:
部署简单,一行命令搞定
升级方便,改个版本号重新 build
镜像小,Alpine 基础镜像不到 30M
日志管理、自动重启都有了
换服务器整个目录拷过去 docker-compose up -d 就完事




