You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

FastAPI+Nginx部署下StaticFiles无法加载问题求助

问题描述

我有一个简单的FastAPI项目,在PyCharm和Docker容器中均可正常运行,但通过Nginx部署时,StaticFiles无法正常加载。

项目结构

├── app
│   ├── main.py
│   ├── static_stuff
│   │   └── styles.css
│   └── templates
│       └── item.html
├── Dockerfile
├── requirements.txt

main.py 代码

from fastapi import Request, FastAPI
from fastapi.responses import HTMLResponse
from fastapi.staticfiles import StaticFiles
from fastapi.templating import Jinja2Templates
import os.path as path


ROOT_PATH =  path.abspath(path.join(__file__ ,"../"))

app = FastAPI(title="my_app", root_path='/my_app')
app.mount("/static_stuff", StaticFiles(directory=f"/{ROOT_PATH}/static_stuff"), name="static")
templates = Jinja2Templates(directory=f"/{ROOT_PATH}/templates")


@app.get("/items/{id}", response_class=HTMLResponse, include_in_schema=False)
async def read_item(request: Request, id: str):
    return templates.TemplateResponse(
        request=request, name="item.html", context={"id": id}
    )

Dockerfile 内容

FROM python:3.13-slim
WORKDIR /my_app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
COPY app ./app
CMD ["gunicorn",  "-k",  "uvicorn.workers.UvicornWorker", "app.main:app", "--bind",  "0.0.0.0:6543"]

EXPOSE 6543

Nginx 配置

location /my_app {
    proxy_pass        http://my_host:6543;
    include           proxy_params;
}

当通过Nginx访问http://my_host/my_app/items/5时,页面功能正常,但静态文件styles.css无法找到。尝试过如下配置但未成功:

location ~ /static_stuff/(.+) {
    proxy_pass        http://my_host:6543;
    include           proxy_params;
}

解决方案

问题核心是静态文件的请求路径与Nginx转发规则不匹配,结合你的配置,按以下步骤修正:

1. 修正模板中静态文件的引用方式

确保item.html里用FastAPI的url_for生成静态文件路径,而非写死路径:

<!-- 错误写法 -->
<link rel="stylesheet" href="/static_stuff/styles.css">

<!-- 正确写法 -->
<link rel="stylesheet" href="{{ url_for('static', path='styles.css') }}">

url_for会自动带上root_path='/my_app'前缀,生成的路径为/my_app/static_stuff/styles.css,让Nginx能正确匹配转发规则。

2. 调整Nginx转发规则(可选,若模板已用url_for可跳过)

你之前的规则匹配的是/static_stuff/xxx,但实际请求路径是/my_app/static_stuff/xxx,需修改Nginx配置:

location /my_app {
    proxy_pass        http://my_host:6543;
    include           proxy_params;
}

# 匹配带my_app前缀的静态文件请求
location ~ /my_app/static_stuff/(.+) {
    proxy_pass        http://my_host:6543/my_app/static_stuff/$1;
    include           proxy_params;
}

如果模板已用url_for生成正确路径,第一条/my_app的规则就能自动转发静态文件请求,无需额外配置。

3. 简化FastAPI的路径配置(避免容器内路径错误)

替换ROOT_PATH的写法,减少路径拼接出错概率:

# 替换原ROOT_PATH定义
ROOT_PATH = path.dirname(path.abspath(__file__))
# 用相对路径挂载静态文件(容器内WORKDIR为/my_app,app目录在该路径下)
app.mount("/static_stuff", StaticFiles(directory=path.join(ROOT_PATH, "static_stuff")), name="static")

内容的提问来源于stack exchange,提问作者saromba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 07:19:59