5

I have a project directory like this:

|-var/www
|-docker-compose.yml
|-app
|--uploads
|---photos
|-Dockerfile

This is my docker-compose.yml file:

myapp:
    build:
      context: myfolder
      dockerfile: Dockerfile
    container_name: flask
    image: api/v1:01
    restart: unless-stopped
    environment:
      APP_ENV: "prod"
      APP_DEBUG: "False"
      APP_PORT: 5000
    volumes:
      - appdata:/var/www

What I want: I want to change app/uploads/photos this folder's permission to 777.This is an upload folder,so user can upload to this folder.

My Dockerfile now is look like this:

FROM python:3.6.8-alpine3.9

ENV GROUP_ID=1000 \
    USER_ID=1000

WORKDIR /var/www/
ADD . /var/www/

RUN apk add --no-cache build-base libffi-dev openssl-dev ncurses-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh

USER www

EXPOSE 5000

After looking in this question,In order to achieve what I want,I tried below:

FROM python:3.6.8-alpine3.9

ENV GROUP_ID=1000 \
    USER_ID=1000

WORKDIR /var/www/
ADD . /var/www/

RUN apk add --no-cache build-base libffi-dev openssl-dev ncurses-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh

RUN chown -R www:www /var/www
RUN chmod -R 777 /var/www/uploads
RUN chmod -R 777 /var/www/uploads/photos


USER www

EXPOSE 5000

But seems like the chmod command in my dockerfile is not taking effect.Cause whenever I upload some files to app/uploads/photos in my code,my nginx server keep getting this error:

PermissionError: [Errno 13] Permission denied: '/var/www/uploads/photos/myfilename.png'

Somebody please help.Please provide a solution for how to change the permission of a folder in Dockerfile.

UPDATE:

I tried to change the permission of /var/www/uploads after build the container and the container is running by doing below:

docker exec -it myapp /bin/sh

then run

chmod -R 777 /var/www/uploads

What I get is chmod: /var/www/uploads: Operation not permitted

Therefore I suspect the this error will also happened when the docker is building,then according to this answer from serverfault, I tried to modify the dockerfile to this:

FROM python:3.6.8-alpine3.9


ENV GROUP_ID=1000 \
    USER_ID=1000

WORKDIR /var/www/
ADD . /var/www/

USER root
RUN chmod -R 777 /var/www/uploads

RUN addgroup -g $GROUP_ID www
RUN adduser -D -u $USER_ID -G www www -s /bin/sh

USER www

RUN apk add --no-cache build-base libffi-dev openssl-dev ncurses-dev
RUN pip install --upgrade pip
RUN pip install -r requirements.txt


EXPOSE 5000

But it still doesnt work. But seem like my above approach is also wrong.Cause I already run in root in the dockerfile.But at the same time,when I access the container in host using docker exec,also getting Operation not permitted.

I am very new in Docker.Just cant figure it out how to get this done.

What I hope to know:

1) How to change the folder var/www/uploads to permission 777?

2) What is the problem causing I cant change the permission from my approach?

3) What is the better way to achieve this? (If any)

1
  • It's already in the accepted answer, but let's still point this out separately, with additional emphasis: You should basically never use chmod 777 - it is insecure and clumsy.
    – tripleee
    Commented Apr 8, 2021 at 5:00

1 Answer 1

5

You really shouldn't set 777, it would probably be better to just change the ownership of that directory to the www account.

Anyway your changes in the Dockerfile really don't matter, because you have a volume (appdata:/var/www) meaning that the permissions you have in the image are masked by your volume.

Your docker exec -it myapp /bin/sh would be failing because that image is running as www which won't be able to run chmod on file not owned by www.

Anyway try just mapping volume into another image temporarily. Do something like docker run --rm -it -v appdata:/var/www debian:buster-slim to start an interactive session to a Debian image with the volume mapped in. That image defaults to running as root, so you should be able to change/fix permissions in the volume. You could also pass the --user option when when running your docker exec.

4
  • omg..omfg...it works!!!!!! Really thank you very much..at the end I able to change the ownership by pass --user option as root during the docker exec operation..
    – ken
    Commented Mar 15, 2020 at 7:52
  • but just 1 more quick question,for ur second point of the permissions you have in the image are masked by your volume.For this,if I dont have appdata:/var/www,then my Dockerfile should work right?(means the permission will changed to 777) .Now it dont works is because I have a volume,and the Dockerfile cant change the permission of the volume..am I right?
    – ken
    Commented Mar 15, 2020 at 7:58
  • 1
    I mean, the permissions in your Dockerfile DOES work from the point of view that the permissions ARE changed in the image, but you are mounting your volume on top of the existing files hiding them. The volume would even work if you were starting with a brand new volume, since docker will copy things the first time a new volume is attached. when the container is started.
    – Zoredache
    Commented Mar 16, 2020 at 6:33
  • You saved my life! I was scratching my head for days and hours. Thanks! Commented Mar 23, 2021 at 18:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .