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
相关产品推荐
相关产品推荐

