Try Traefik
写在前面:
请务必注意不要直接复制粘贴配置文件,特别是labels里面的参数。
Traefik (发音同Traffic)是一个用 Go 写的反向代理工具,可以完美地跟 Docker 整合在一起使用,又简洁又优雅。
目前我服务器上正在用的是 Caddy 或者 Cloudflare Tunnel 和 Nginx 一堆工具糊在一起的拖拉机式的方案,这样不够优雅。所以先试试 Traefik 的水,之后再逐步把拖拉机换成法拉利(x
需要注意的是 Traefik 只是一个纯反向代理的工具。
她不能像 Caddy/Nginx 一样只用一个就能 host 静态资源或者运行 php 程序等。
如果有大量的 host 静态文件的需求的话,最好还是老老实实选择 Caddy ,或者用 Traefik 放在前面反代 Caddy。
常规安装
traefik/docker-compose.yml
version: '3'
services:
traefik:
image: traefik:v2.9
container_name: traefik
restart: always
ports:
- 80:80
- 443:443
# 8080 是 Trarfik dashboard 的连接埠,如果不需要的话可以不要。
- 8080:8080
volumes:
# 允许 Traefik 监听 docker 事件
- /var/run/docker.sock:/var/run/docker.sock
- ./plugins-storage:/plugins-storage
- ./traefik.yml:/etc/traefik/traefik.yml:ro
# Traefik 监听配置的目录
- ./config:/config:ro
# 放 ssl 证书的目录
- ./cert:/cert:ro
networks:
proxy:
networks:
# 因为放了在 traefik 目录里,所以最终这个 network 的名字会叫作 `traefik_proxy`
# 记住这个 `traefik_proxy` ,后面要用。
proxy:
driver: bridge
traefik/traefik.yml
Tearfik 的主配置文件
entryPoints:
http:
address: ":80"
https:
address: ":443"
providers:
docker:
watch: true
network: traefik_proxy
file:
directory: "/config"
watch: true
api:
dashboard: true
insecure: true
我所理解的 Provider 是一种配置的“来源”,比方说上述yaml文件定义了两个 provider ,分别是 docker
和 file
。
那么 traefik 就会从 docker 的 /var/run/docker.sock
中实时读取容器所设置的 labels
作为自己的配置文件,后面会讲。
Traefik 也会实时监听(文件发生更改的话会实时更新,不需要重启 Traefik ) /config
下面的文件作为自己的配置文件作为自己的配置文件。
然后我们还需要一个文件来告诉 Traefik 我们的 https 证书放了在哪儿。
这个目录下的配置文件都能热更新,所以如果需要增加证书的话直接编辑就好。
traefik/config/tls.yml
tls:
certificates:
- certFile: /cert/mihoyo.me.cert
keyFile: /cert/mihoyo.me.key
Traefik 的配置基本完成了。
启动两个新容器试试看效果。
whoami/docker-compose.yml
version: '3'
services:
whoami:
image: traefik/whoami
container_name: whoami
labels:
- "traefik.http.routers.whoami.rule=Host(`test1.mihoyo.me`)"
- "traefik.http.routers.whoami.tls=true"
- "traefik.http.routers.whoami.entrypoints=https"
networks:
traefik_proxy:
networks:
traefik_proxy:
external: true
whoami1/docker-compose.yml
version: '3'
services:
whoami:
image: traefik/whoami
container_name: whoami1
labels:
- "traefik.http.routers.whoami1.rule=Host(`test2.mihoyo.me`)"
- "traefik.http.routers.whoami1.tls=true"
- "traefik.http.routers.whoami1.entrypoints=https"
networks:
traefik_proxy:
networks:
traefik_proxy:
external: true
然后于浏览器中访问 test1.mihoyo.me
和 test2.mihoyo.me
,
可以看到显示出来了两个不同的 hostname ,分别是两个 container ID.
证明反向代理有在正常工作。
Hostname: 38d30d1e7434
...
Hostname: 7330855b4133
...
在 dashboard 里面也能看见自动添加了两条记录。
使用 Let’s Encrypt
若要使用 Let’s Encrypt 而不是自己的证书,就在 traefik.yaml
中增加一个 Certificates Resolver.
推荐使用 TLS Challenge ,这样不会有那么多幺蛾子。
traefik.yaml
certificatesResolvers:
le:
acme:
email: [email protected]
storage: /cert/acme.json
tlsChallenge: {}
然后在 docker-compose.yaml
中的服务增加以下label:
labels:
- "traefik.http.routers.example.tls.certresolver=le"
转发到非标准端口
Traefik 在默认情况下会使用80端口。如果你的镜像给你整的不是这个标准的端口,而是像8080、8888这种的话,需要在 docker-compose.yaml
中添加如下 label 来指定端口。
labels:
- "traefik.http.services.example.loadbalancer.server.port=443"
references:
Using traefik as proxy in docker
10 分鐘內用 Traefik 架設 Drone 搭配 GitHub 服務