'Docker non-root user can't write external volume

I use docker-compose to run two docker containers, one for the server and another one for the MySql database. The server receives video files from an API endpoint and saves them into the /app/media folder.

However, it cannot access the /media folder which is an external volume I pointed to the local disk.

I already tried to create and change the owner for the folder manually (See the Dockerfile below).

I also use a similar method to mount the MySql database. It seems to read and write just fine.

The Dockerfile in my server folder:

FROM python:3.9.11
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
RUN apt-get update \
    && apt-get install -y --no-install-recommends \
    postgresql-client iputils-ping netcat
RUN groupadd app && useradd -m -g app app
RUN mkdir /app
WORKDIR /app
COPY . .
RUN chown -R app:app /app
RUN mkdir -p /app/media
RUN chown -R app:app /app/media
RUN chmod go+w+x /app/media
USER app
RUN pip install --upgrade pip \
    && pip install -r requirements.txt
EXPOSE 3000

The docker-compose.yml file for the project:

version: '3.8'

services:
  backend:
    depends_on:
      - db
    build: ./server
    env_file:
      - .env
    ports:
      - 3000:3000
    command:
      ['sh', './wait-for.sh', 'db:3306', '--', 'sh', './docker-entrypoint.sh']
    volumes:
      - ./media:/app/media

  db:
    image: mysql:8.0.28-oracle
    command: --default-authentication-plugin=mysql_native_password
    env_file:
      - .env
    ports:
      - 3306:3306
    volumes:
      - db:/var/lib/mysql

volumes:
  db:

The error from the server after calling the POST API endpoint is:

PermissionError at /api/survey-responses/
[Errno 13] Permission denied: '/app/media/surveycore'
...
Exception Location: /usr/local/lib/python3.9/os.py, line 225, in makedirs
...

surveycore is the name of a Django app.

When I access the docker container from another terminal, I got:

-rw-rw-r-- 1 app  app    111 Mar 23 11:38 .dockerignore
-rw-rw-r-- 1 app  app    468 Mar 30 10:23 Dockerfile
drwxrwxr-x 1 app  app   4096 Mar 15 09:32 db
-rw-rw-r-- 1 app  app    172 Mar 23 10:50 docker-entrypoint.sh
-rwxrwxr-x 1 app  app    672 Mar 10 01:31 manage.py
drwxr-xr-x 2 root root  4096 Mar 30 09:58 media
-rw-rw-r-- 1 app  app   1502 Mar 23 09:57 requirements.txt
drwxrwxr-x 1 app  app   4096 Mar 15 10:25 surveycore
-rw-rw-r-- 1 app  app   3267 Mar 23 09:57 wait-for.sh

Everything else is assigned to the correct user app, except media.

The server was tested on a local machine. Nothing wrong with it.

I saw some suggestions about accessing the container from another terminal as the root user, and giving the user right this way. That seems like a hack to me, is there a proper way to config the docker file to fix the issue?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source