I've a simple FastAPI project. It is running correctly in pycharm and in the docker container. When running via nginx, the StaticFiles
are not delivered.
Structure is like this:
├── 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}
)
The application is running in a docker container:
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
The nginx configuration looks like this:
location /my_app {
proxy_pass http://my_host:6543;
include proxy_params;
}
When calling the nginx -> http://my_host/my_app/items/5
Everything works except the staticfiles. The styles.css is not found. What am I doing wrong?
I tried something like this, but I had no success
location ~ /static_stuff/(.+) {
proxy_pass http://my_host:6543;
include proxy_params;
}
It seems like there is a bug in FastAPI with root_path
parameter for mounted paths.
If you specify root_path
as a parameter of __init__
it expects additional my_app/
in path. So, your files are available on /my_app/my_app/static_stuff/
instead of /my_app/static_stuff/
.
Try specifying root_path
as an argument of server (e.g. uvicorn main:app --root-path my_app
for uvicorn) instead of passing it as a parameter of __init__
.