Разрешение отклонено при загрузке файла Docker Fastapi

Я сталкиваюсь с ошибкой при попытке загрузить файл в конечную точку 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

Ваша команда chown не будет работать, поскольку на изображении нет группы appgroup. Группа будет иметь то же имя, что и пользователь, appuser.

datawookie 22.05.2024 06:20
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
103
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 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

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/

Вероятно, есть лучшие способы сделать это, но этот вариант, безусловно, работает.

Другие вопросы по теме