从 Traefik 代理后面的 FastAPI 应用程序公开静态文件

问题描述 投票:0回答:1

在我的 FastAPI 应用程序中,我安装了

static
目录来提供静态文件,如下所示:

app.mount('/static', StaticFiles(directory='static'), name='static')

FastAPI 应用程序从定义如下的 Docker 容器内部运行:

fhback:
    container_name: fhback
    build:
      context: ./back
      dockerfile: Dockerfile
    restart: unless-stopped
    expose:
      - 8000
    command: "gunicorn --workers 6 --timeout 60 --bind 0.0.0.0:8000 -k uvicorn.workers.UvicornWorker main:app"
    volumes:
      - ./back:/app
    labels:
      - traefik.enable=true
      - traefik.http.routers.fhback.rule=Host(`example.com`) && PathPrefix(`/api`)
      - traefik.http.routers.fhback.entrypoints=https
      - traefik.http.routers.fhback.tls.certresolver=le
      - traefik.http.middlewares.firehouse-compress.compress=true
      - traefik.http.middlewares.fhback-stripprefix.stripprefix.prefixes=/api
      - traefik.http.routers.fhback.middlewares=firehouse-compress,fhback-stripprefix

通过这些 Traefik 标签,我可以使用

https://example.com/api/docs
访问我的 Swagger,还可以使用
https://example.com/api/...
(外部)或
http://fhouse:8000/api/...
(本地,从 Docker)从前端调用 API 端点。

但我永远无法访问

static
目录中的静态文件!当我从 Docker 网络中的任何 Docker 容器执行
http://fhouse:8000/api/static/any-file.txt
时,它工作正常。但是当我尝试
https://example.com/api/static/any-file.txt
时,出现连接错误。我意识到我必须对 Traefik 配置做一些事情...有什么想法吗?

docker proxy fastapi traefik static-files
1个回答
0
投票
├── back
│   ├── Dockerfile
│   ├── main.py
│   ├── requirements.txt
│   └── static
│       └── test.html
└── docker-compose.yml

Traefik 和 API 都设置为服务。

🗎

docker-compose.yml

version: "3"

services:
  traefik:
    container_name: traefik
    image: traefik:v2.5
    command:
      - "--log.level=DEBUG"
      - "--api.insecure=true"
      - "--providers.docker=true"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"

  fhback:
    container_name: fhback
    build:
      context: ./back
      dockerfile: Dockerfile
    restart: unless-stopped
    volumes:
      - ./back:/app
    labels:
      - traefik.enable=true
      - traefik.http.routers.fhback.rule=Host(`example.com`) && PathPrefix(`/`)
      - traefik.http.services.fhback.loadbalancer.server.port=8000
      - traefik.http.middlewares.firehouse-compress.compress=true
      - traefik.http.routers.fhback.middlewares=firehouse-compress,fhback-stripprefix
      - traefik.http.middlewares.testheader.headers.customresponseheaders.X-Test-Header=TraefikProxy
      - traefik.http.routers.fhback.middlewares=testheader
    depends_on:
      - traefik

networks:
  default:
    external:
      name: traefik

🗎

back/Dockerfile

FROM python:3.11.4-slim

COPY requirements.txt .

RUN pip3 install --no-cache-dir -r requirements.txt

WORKDIR /app

COPY . /app

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

静态文件被直接烘焙到图像中。不过,您可以使用卷挂载从主机共享静态文件。

🗎

back/main.py

from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()

app.mount('/static', StaticFiles(directory='static'), name='static')

@app.get("/")
async def root():
    return {"message": "Hello World"}

🗎

requirements.txt

fastapi==0.109.2
uvicorn==0.27.1

测试:

curl -v --resolve example.com:80:127.0.0.1 http://example.com/static/test.html

我通过

docker-compose.yml
中的 Traefik 标签添加了响应标头。如果您查看下面的输出,您将看到该标头,确认响应来自 Traefik。您还可以在屏幕截图顶部面板的日志中看到它。

© www.soinside.com 2019 - 2024. All rights reserved.