Получение Permission denied: '/vol/web/media' при попытке создать файл в моем django-приложении

Вот мой dockerfile.

    FROM python:3.9-alpine3.13
    
    ENV PYTHONUNBUFFERED 1
    
    COPY ./requirements.txt /requirements.txt
    COPY ./electron /electron
    COPY ./scripts /scripts
    
    WORKDIR /electron
    EXPOSE 8000
    
    RUN apk add --no-cache --virtual .build-deps gcc musl-dev
    
    RUN python3.9 -m venv /py && \
        /py/bin/pip install --upgrade pip setuptools wheel && \
        apk add --update --no-cache postgresql-client && \
        apk add --update --no-cache --virtual .temp-deps \
            build-base postgresql-dev musl-dev linux-headers && \
        mkdir -p /vol/web/media && \ <----- The problem is located at this level
        /py/bin/pip install -r /requirements.txt && \
        adduser --disabled-password --no-create-home ozangue && \
        chown -R ozangue:ozangue /vol && \
        chmod -R 755 /vol && \
        chown -R ozangue:ozangue /vol/web/media && \
        chmod -R 755 /vol/web/media && \
        chmod -R +x /scripts
    
    ENV PATH="/scripts:/py/bin:$PATH"

USER ozangue

CMD ["run.sh"]

Не удается сохранить модель, содержащую файл. Потому что этот файл должен быть сохранен в /vol/web/media
. Часть кода, которая создает проблему, выглядит следующим образом (в файле views.py):

file = request.FILES["excel_file"]
file_obj = FileModelXSL(file=excel_file)
fichier_obj = fichier_obj.save()

в файле settings.py

STATIC_URL = '/static/static/'
MEDIA_URL = '/static/media/'

MEDIA_ROOT = '/vol/web/media'
STATICFILES_DIRS = (BASE_DIR / 'static',)
STATIC_ROOT = '/vol/web/static'

Когда я собираю контейнер, я не получаю никаких ошибок, но у меня создается впечатление, что /vol/web/media: mkdir -p /vol/web/media не создается. Но если бы он не был создан, то строка chmod -R 755 /vol/web/media должна была бы выдать ошибку.
Нужна помощь, пожалуйста

Когда вы монтируете volumes: в контейнер, содержимое каталога хоста или именованного тома полностью скрывает то, что было в образе до этого.

В вашем случае вы устанавливаете ./data/web поверх /vol/web на изображении. Это означает, что mkdir /vol/web/media в Dockerfile становится скрытым: существует ли каталог media и какой пользователь им владеет, полностью зависит от содержимого каталога ./data/web на хосте.

Если вы можете удалить эти volumes:, это будет лучшим решением. Например, вам не нужно монтировать том, скрывающий каталог /electron образа, поскольку этот код уже COPY встроен в образ.

В противном случае необходимо убедиться, что каталог существует на хосте

mkdir ./data/web/static ./data/web/media

Чтобы сделать каталог доступным для записи из контейнера, нужно выяснить, какой числовой идентификатор пользователя владеет этим каталогом. Обычно это ваш текущий пользователь, и id -u сообщит вам его числовой uid. В файле Compose вам нужно установить user: на этот числовой uid. Вам не нужно специально "создавать пользователя", а встраивать uid в Dockerfile - не самая лучшая практика.

user: '1000'
Вернуться на верх