先说问题:Traefik 本身是不支持代理静态文件的。原因参考: issue 4240

为什么

这里简单说一下为什么吧,因为它的设计原则是:Separation of Concerns。所以traefik并没有提供代理以外的功能,而静态文件需要一个静态文件服务器。

怎么实现静态文件代理

为什么需要静态文件代理?其实主要是为了部署前端项目文件。

traefik 反代需要 route + service ,因此需要一个静态文件服务器来提供服务,如果只是个人使用,完全可以使用nginx来做静态文件服务器。

Nginx - .env 文件

1
2
3
4
# 应用名称
SERVICE_NAME=nginx_server
# 使用的应用镜像
DOCKER_IMAGE=nginx:1.21.0-alpine

Nginx - docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
version: '3.6'

services:
  gitea:
    image: ${DOCKER_IMAGE}
    container_name: ${SERVICE_NAME}
    environment:
      - USER_UID=1000
      - USER_GID=1000
    networks:
      - traefik
    restart: unless-stopped
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik"
      - "traefik.http.services.nginxserverhttp.loadbalancer.server.scheme=http"
      - "traefik.http.services.nginxserverhttp.loadbalancer.server.port=80"
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
      - ./conf:/etc/nginx/conf.d
      - ./data:/data
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
    healthcheck:
      test: ["CMD-SHELL", "curl --fail http://127.0.0.1 || exit 1"]
      interval: 5s

networks:
  traefik:
    external: true

将静态文件放入 data 目录,对应的nginx配置文件放入 conf 目录。

这样可以创建Nginx的container,同时labels中定义了nginx的service。

Traefik Routes 配置示例

这里在traefik的dynamic config新增了routes,没有在labels中定义,因为我想在后续有新的项目需要部署时可以复用这个service。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
[http.routers]
  [http.routers.testroute]
    entryPoints = ["http"]
    middlewares = ["https-redirect@file"]
    rule = "Host(`domain`)"
    service = "nginxserverhttp"
  [http.routers.testroutessl]
    entryPoints = ["https"]
    middlewares = ["gzip@file"]
    rule = "Host(`domain`)"
    service = "nginxserverhttp"
  [http.routers.testroutessl.tls]
    certresolver = "le"

结论

Traefik 实现静态文件代理的方式,就是创建静态代理服务器的container,然后配置service和rule,实现静态文件的访问。

Traefik 最大的好处是支持服务自动发现,就俩字儿,好用。