Я сталкиваюсь с ошибкой при попытке загрузить файл в конечную точку FastAPI, на которой он работает нормально localhost, но я получаю сообщение об ошибке при запуске его в контейнере.
Ошибка, которую я получаю:
File "/app/main.py", line 26, in say_hello
with open(file_path, "wb") as f:
^^^^^^^^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied: 'uploads/h.png'
Моя конечная точка загрузки:
@app.post("/letter")
async def say_hello(file: UploadFile = File(...)):
file_path = f"uploads/{file.filename}"
with open(file_path, "wb") as f:
f.write(await file.read())
return process_image(file_path)
Мой Dockerfile:
# syntax=docker/dockerfile:1
ARG PYTHON_VERSION=3.12.3
FROM python:${PYTHON_VERSION}-slim as base
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
# Set the permissions for all files
RUN chown -R appuser:appgroup /app
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
python -m pip install -r requirements.txt
# Switch to the non-privileged user to run the application.
USER appuser
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Я попытался установить разрешение для пользователя по умолчанию, добавив разрешение Dockerfile, но ничего не изменилось:
# Set the permissions for all files
RUN chown -R appuser:appgroup /app






Я считаю, что вам нужно изменить владельца файла после того, как вы скопировали его на свое изображение.
ARG PYTHON_VERSION=3.12.3
FROM python:${PYTHON_VERSION}-slim as base
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /app
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
RUN --mount=type=cache,target=/root/.cache/pip \
--mount=type=bind,source=requirements.txt,target=requirements.txt \
python -m pip install -r requirements.txt
COPY . .
RUN chown -R appuser:appuser /app/uploads
EXPOSE 8000
USER appuser
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
Это приведет к тому, что каталог /app/uploads в любом контейнере будет доступен для записи appuser. Предполагается, что на хосте есть каталог uploads, который будет скопирован в изображение.
Однако здесь есть проблема: любые файлы, загруженные в работающий контейнер, будут существовать только внутри контейнера и будут потеряны, когда контейнер остановится.
Если вы хотите сохранить эти файлы, вам, вероятно, потребуется выполнить монтирование тома при запуске образа. При выполнении -v ./uploads/:/app/uploads вы бы сделали что-то вроде docker run. Однако в этом случае вам необходимо убедиться, что каталог uploads/ на хосте будет доступен для записи и в контейнере. Один из способов сделать это — предоставить пользователю, группе и другим лицам доступ на запись к папке на хосте.
chmod a+w uploads/
Вероятно, есть лучшие способы сделать это, но этот вариант, безусловно, работает.
Ваша команда
chownне будет работать, поскольку на изображении нет группыappgroup. Группа будет иметь то же имя, что и пользователь,appuser.