本文使用「署名 4.0 国际 (CC BY 4.0)」许可协议,欢迎转载、或重新修改使用,但需要注明来源。 [署名 4.0 国际 (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.zh) 本文作者: 苏洋 创建时间: 2020年10月04日 统计字数: 3427字 阅读时间: 7分钟阅读 本文链接: https://soulteary.com/2020/10/04/frp-in-docker.html ----- # 容器化 FRP 使用方案 最近在折腾过程中,使用到了 FRP 这款软件,碰巧作者在几天前更新的 `v0.34.1` 版本只发布了容器版本,并未像之前一样发布多种编译版本。 距离上一次写 FRP [相关的内容](https://soulteary.com/2018/06/13/server-log-collection-for-individual-developers.html),已经过去了两年。本文就基于官方容器版本,介绍该软件的简单使用方法吧。 ## 在容器中使用 FRP 服务端 首先在服务端找一个合适的目录,创建 **frps.ini** 配置文件,考虑到后续的便捷使用,这里我们使用环境变量来对配置进行抽象。 ```TeXT [common] bind_port = {{ .Envs.FRP_SERVER_PORT }} token = {{ .Envs.FRP_SERVER_TOKEN }} dashboard_addr = 0.0.0.0 dashboard_port = {{ .Envs.FRP_ADMIN_PORT }} dashboard_user = {{ .Envs.FRP_ADMIN_USER }} dashboard_pwd = {{ .Envs.FRP_ADMIN_PASS }} ``` 接着,就可以在 `docker-compose.yml` 中使用环境变量来对程序的服务端进行“动态”配置了: ```yaml version: "3.7" services: frps: restart: always container_name: frps image: fatedier/frps:v0.34.1 volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - ./frps.ini:/app/frps.ini:ro command: frps -c /app/frps.ini ports: - 9870:9870 - 7890:7890 - YOURPORT:YOURPORT environment: - FRP_SERVER_PORT=9870 - FRP_SERVER_TOKEN=CMW9viCpy1FZ - FRP_ADMIN_PORT=7890 - FRP_ADMIN_USER=soulteary - FRP_ADMIN_PASS=soulteary networks: - frps logging: driver: "json-file" options: max-size: "1m" # docker network create frps networks: frps: external: true ``` 上面配置中需要注意的是,`ports` 字段中,目前只声明了 `FRP_SERVER_PORT` 服务端通讯接口和 `FRP_ADMIN_PORT` 服务端管理接口,所以我们需要再根据自己的情况添加一个/一些应用接口。 当然,更好的方案是搭配 Traefik 使用服务发现来对外提供服务。后面有机会,我再行文详述。 在服务端使用 `docker-compose up -d` 启动服务,如果顺利的话,将看到类似下面的日志: ```TeXT frps | 2020/10/04 19:52:27 [I] [service.go:190] frps tcp listen on 0.0.0.0:9870 frps | 2020/10/04 19:52:27 [I] [service.go:289] Dashboard listen on 0.0.0.0:9870 frps | 2020/10/04 19:52:27 [I] [root.go:212] start frps success ``` 接着我们来配置客户端。 ## 在容器中使用 FRP 客户端 同服务端一样,我们先确定客户端配置 **frpc.ini** 的“架子”: ```TeXT [common] server_addr = {{ .Envs.FRP_SERVER_ADDR }} server_port = {{ .Envs.FRP_SERVER_PORT }} token = {{ .Envs.FRP_SERVER_TOKEN }} [app] type = tcp remote_port = {{ .Envs.APP_REMOTE_PORT }} local_ip = {{ .Envs.APP_HOST }} local_port = {{ .Envs.APP_PORT }} ``` 接着是完成客户端的 `docker-compose.yml` 配置文件: ```yaml version: "3.7" services: frpc: restart: always image: fatedier/frpc:v0.34.1 volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - ./frpc.ini:/app/frpc.ini:ro environment: - FRP_SERVER_ADDR=123.456.789.012 - FRP_SERVER_PORT=9870 - FRP_SERVER_TOKEN=CMW9viCpy1FZ - APP_REMOTE_PORT=YOURPORT - APP_HOST=YOUR_APP_HOST - APP_PORT=YOUR_APP_PORT networks: - frpc logging: driver: "json-file" options: max-size: "1m" # docker network create frpc networks: frpc: external: true ``` 这里 `APP_HOST` 和 `APP_PORT` 指代的是 FRPC 客户端在容器网络中能够访问到的要映射到前文服务器中的应用的地址及端口。而 `APP_REMOTE_PORT` 指的则是上文中的 `YOURPORT`,比如 80 端口、或者 443 端口。 在客户端同样使用 `docker-compose up -d` 启动服务,然后可以看到客户端的运行日志: ```TeXT frpc | 2020/10/04 20:42:56 [I] [service.go:288] [62e9e2de742523fe] login to server success, get run id [62e9e2de742523fe], server udp port [0] frpc | 2020/10/04 20:42:56 [I] [proxy_manager.go:144] [62e9e2de742523fe] proxy added: [confluence-app] frpc | 2020/10/04 20:42:56 [I] [control.go:180] [62e9e2de742523fe] [app] start proxy success ``` 服务端此时也会多一条连接日志: ```TeXT frps | 2020/10/04 20:42:56 [I] [control.go:446] [62e9e2de742523fe] new proxy [app] success ``` 至此,FRP 在容器内的使用就全部完毕了,随后就由你自由发挥啦。 ## 其他 软件的[发布页面](https://github.com/fatedier/frp/releases)中,作者提到了 “Official docker image support on DockerHub and Github registry.” 查阅 DockerHub 官方页面,可以看到下面两个镜像仓库中有两个不同的推送记录,不过目前使用人数不多,或许是因为作者尚未给出明确的文档示例吧(开源仓库/容器仓库): - [https://hub.docker.com/r/fatedier/frps](https://hub.docker.com/r/fatedier/frps) - [https://hub.docker.com/r/fatedier/frpc](https://hub.docker.com/r/fatedier/frpc) 不过在短暂使用几天后发现,当前版本不论是镜像尺寸还是运行性能都还不错,而且相比较之前的版本,在容器中使用更加方便了,希望后续作者有时间能够完善文档吧。 ## 最后 FRP 是一款优秀的软件,随着越来越多的廉价公有云的面世,使用这款软件搭配家用服务器使用,可以大幅降低调试开发成本、以及简化一些临时场景下的复杂组网,值得一试。 最后,希望本文能对想在容器中玩 FRP 的你有帮助。 --EOF