从caddy迁移到traefik
最开始,我服务器的反向代理使用caddy,配置非常方便
后面,脑子抽抽了换了nginx+certbot,也还算方便
后面不知道为啥又换了caddy,不过当时选择了docker中的caddy
再后来,也就是现在,脑子抽抽换了traefik,也不知道为啥
还是记录一下折腾traefik的操作,希望以后反复横跳的我不用再踩坑
之前
我的阿里云ECS上主要运行以下几个服务:
Lobe Chat
Minio(为Lobe Chat提供s3存储)
Logto(单点登录)
Vaultwarden
Halo
如果使用caddy的话,配置反向代理非常方便
{
email personal@zhelearn.com
}
vaultwarden.zhelearn.com {
encode zstd gzip
header / {
Strict-Transport-Security "max-age=31536000;"
X-XSS-Protection "0"
X-Frame-Options "DENY"
X-Robots-Tag "noindex, nofollow"
X-Content-Type-Options "nosniff"
-Server
-X-Powered-By
-Last-Modified
}
reverse_proxy {$TARGET_IP}:11001 {
header_up X-Real-IP {remote_host}
header_up Host {host}
}
}
mail.zhelearn.com {
encode zstd gzip
header {
Strict-Transport-Security "max-age=63072000"
Content-Security-Policy-Report-Only "default-src 'self' https:; script-src 'self' https: 'unsafe-inline' 'unsafe-eval'; object-src 'none'; frame-src 'self';"
}
reverse_proxy https://qiye.aliyun.com
}
lobe.zhelearn.com {
header Strict-Transport-Security "max-age=63072000"
reverse_proxy {$TARGET_IP}:3210
}
auth-api.zhelearn.com {
header Strict-Transport-Security "max-age=63072000"
reverse_proxy {$TARGET_IP}:3001
}
auth-ui.zhelearn.com {
header Strict-Transport-Security "max-age=63072000"
reverse_proxy {$TARGET_IP}:3002
}
s3-api.zhelearn.com {
header Strict-Transport-Security "max-age=63072000"
reverse_proxy {$TARGET_IP}:9000
}
s3-ui.zhelearn.com {
header Strict-Transport-Security "max-age=63072000"
reverse_proxy {$TARGET_IP}:9001
}
blog.zhelearn.com {
header Strict-Transport-Security "max-age=63072000"
reverse_proxy {$TARGET_IP}:8090
}
然后在docker-compose.yaml
中,启动caddy容器即可
services:
caddy:
image: caddy:latest
container_name: caddy
restart: always
ports:
- "80:80"
- "443:443"
environment:
- TARGET_IP=172.20.164.215
volumes:
- ./data/caddy/Caddyfile:/etc/caddy/Caddyfile
(其中TARGET_IP
是我服务器的内网IP)
之后
现在切换到traefik,事情貌似变得复杂了起来,但是似乎也容易了一些(?)
可以直接在docker-compose中为对应的容器添加label来配置反向代理
首先是添加traefik的容器
services:
traefik:
image: traefik:v3.1
command:
- "--api.insecure=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=personal@zhelearn.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- "./traefik/letsencrypt:/letsencrypt"
- "/var/run/docker.sock:/var/run/docker.sock"
labels:
- "traefik.enable=true"
# Global Settings
- "traefik.http.middlewares.redirect-to-https.redirectscheme.scheme=https"
# Traefik dashboard basic auth
- "traefik.http.middlewares.traefik-auth.basicauth.users=username:encoded password"
- "traefik.http.routers.traefik-http.rule=Host(`traefik.zhelearn.com`)"
- "traefik.http.routers.traefik-http.entrypoints=web"
- "traefik.http.routers.traefik-http.middlewares=redirect-to-https"
- "traefik.http.routers.traefik-https.rule=Host(`traefik.zhelearn.com`)"
- "traefik.http.routers.traefik-https.entrypoints=websecure"
- "traefik.http.routers.traefik-https.tls=true"
- "traefik.http.routers.traefik-https.tls.certresolver=myresolver"
- "traefik.http.routers.traefik-https.service=traefik"
- "traefik.http.routers.traefik-https.middlewares=traefik-auth"
- "traefik.http.services.traefik.loadbalancer.server.port=8080"
restart: always
其中我开启了traefik dashboard,使用basic auth进行认证,生成密码的方法是:
echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
一般容器
接下来只需要配置其他容器的label,traefik就可以为他们进行反向代理
例如 Vaultwarden
services:
......
vaultwarden:
image: vaultwarden/server:latest
ports:
- "11001:80"
volumes:
- "./vaultwarden/data:/data"
env_file:
- ./vaultwarden/.env
labels:
- "traefik.enable=true"
- "traefik.http.routers.vaultwarden-http.rule=Host(`vaultwarden.zhelearn.com`)"
- "traefik.http.routers.vaultwarden-http.entrypoints=web"
- "traefik.http.routers.vaultwarden-http.middlewares=redirect-to-https"
- "traefik.http.routers.vaultwarden-https.rule=Host(`vaultwarden.zhelearn.com`)"
- "traefik.http.routers.vaultwarden-https.entrypoints=websecure"
- "traefik.http.routers.vaultwarden-https.tls=true"
- "traefik.http.routers.vaultwarden-https.tls.certresolver=myresolver"
restart: always
有多个端口的容器
不过也有特殊情况,例如minio,要开放两个端口,并代理到不同的域名上,配置就稍微复杂一点
如下
services:
......
minio:
image: minio/minio
ports:
- "9000:9000"
- "9001:9001"
volumes:
- "./minio/data:/etc/minio/data"
env_file:
- ./minio/.env
labels:
- "traefik.enable=true"
- "traefik.http.routers.minio-api-http.rule=Host(`minio-api.lobe.zhelearn.com`)"
- "traefik.http.routers.minio-api-http.entrypoints=web"
- "traefik.http.routers.minio-api-http.middlewares=redirect-to-https"
- "traefik.http.routers.minio-api-http.service=minio-api"
- "traefik.http.routers.minio-api-https.rule=Host(`minio-api.lobe.zhelearn.com`)"
- "traefik.http.routers.minio-api-https.entrypoints=websecure"
- "traefik.http.routers.minio-api-https.tls=true"
- "traefik.http.routers.minio-api-https.tls.certresolver=myresolver"
- "traefik.http.routers.minio-api-https.service=minio-api"
- "traefik.http.services.minio-api.loadbalancer.server.port=9000"
- "traefik.http.routers.minio-ui-http.rule=Host(`minio-ui.lobe.zhelearn.com`)"
- "traefik.http.routers.minio-ui-http.entrypoints=web"
- "traefik.http.routers.minio-ui-http.middlewares=redirect-to-https"
- "traefik.http.routers.minio-ui-http.service=minio-ui"
- "traefik.http.routers.minio-ui-https.rule=Host(`minio-ui.lobe.zhelearn.com`)"
- "traefik.http.routers.minio-ui-https.entrypoints=websecure"
- "traefik.http.routers.minio-ui-https.tls=true"
- "traefik.http.routers.minio-ui-https.tls.certresolver=myresolver"
- "traefik.http.routers.minio-ui-https.service=minio-ui"
- "traefik.http.services.minio-ui.loadbalancer.server.port=9001"
restart: always
command: >
server /etc/minio/data --address ":9000" --console-address ":9001"
这样就能够使9000对应api,而9001对应ui了
容器之外
如果在需要代理的端口在docker之外,那么接下来的配置就麻烦一点了
首先要修改traefik容器的配置,添加一个文件的provider
services:
traefik:
image: traefik:v3.1
command:
- "--api.insecure=true"
- "--api.dashboard=true"
- "--providers.docker=true"
- "--providers.file=true"
- "--providers.file.watch=true"
- "--providers.file.filename=/etc/traefik/rules.yaml"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
- "--certificatesresolvers.myresolver.acme.email=personal@zhelearn.com"
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
ports:
- "80:80"
- "8080:8080"
- "443:443"
volumes:
- "./traefik/letsencrypt:/letsencrypt"
- "./traefik/rules.yaml:/etc/traefik/rules.yaml"
- "/var/run/docker.sock:/var/run/docker.sock:ro"
......
接下来添加rules.yaml,例如我这里
http:
routers:
webhook-http:
rule: "Host(`webhook.zhelearn.com`)"
entryPoints:
- web
middlewares:
- redirect-to-https
service: webhook
webhook-https:
rule: "Host(`webhook.zhelearn.com`)"
entryPoints:
- websecure
tls:
certResolver: myresolver
service: webhook
services:
webhook:
loadBalancer:
servers:
- url: "http://172.20.164.215:5000"
middlewares:
redirect-to-https:
redirectScheme:
scheme: "https"
permanent: true
这样就可以对docker网络之外的端口进行代理了
最后
除了配置traefik的字数多一点,好像也没啥不好的,当然也没啥好的)
评论
其他文章