Getting Permission denied: '/vol/web/media' when trying to create file in my django application

Here is my 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"]

I cannot save a model containing a file. Because this file must be saved in /vol/web/media
The part of the code that poses a problem is as follows (in views.py):

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

in 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'

When I build the container, I don't get any errors but I have the impression that /vol/web/media: mkdir -p /vol/web/media is not created. But if it was not created the line chmod -R 755 /vol/web/media should have returned an error.
Need help please

When you mount volumes: into a container, the content of the host directory or named volume completely hides what was in the image before.

In your case, you're mounting ./data/web over /vol/web in the image. That means that the mkdir /vol/web/media in the Dockerfile gets hidden: whether or not there is a media directory, and which user owns it, completely depends on the contents of the ./data/web directory on the host.

If you can delete these volumes:, that's the best solution. For example, you do not need a volume mount hiding the image's /electron directory since that code is already COPYed into the image.

Otherwise you need to make sure the directory exists on the host

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

To make the directory writable from inside the container you need to figure out what numeric user ID owns the directory. Usually it is your current user, and id -u will tell you its numeric uid. In your Compose file, you need to set user: to that numeric uid. You do not specifically need to "create the user" and it's not a good practice to embed the uid in the Dockerfile.

user: '1000'
Back to Top