EnterSB
EnterSB

Reputation: 1162

Docker-compose and named volume permission denied

There is docker-compose that uses base Dockerfile created image for application.

Dockerfile looks similar to below. Some lines are omitted for reason.

FROM ubuntu:18.04

RUN set -e -x ;\
    apt-get -y update ;\
    apt-get -y upgrade ;

...

USER service

When using this image in docker-compose and adding named volume to service, folder in named volume is not accessible, with message Permission denied. Part from docker-compose looks as below.

version: "3.1"
    services:
        myapp:
            image: myappimage
            command:
                - /myapp
            ports:
                - 12345:1234
            volumes:
                - logs-folder:/var/log/myapp

volumes:
    logs-folder:

My assumption was that USER service line is issue, which I confirmed by setting user: root in myapp service.

Now, question is next. I would like to avoid manually creating volume and setting permissions. I would like it to be automated using docker-compose.

Is this possible and if yes, how can this be done?

Upvotes: 19

Views: 51602

Answers (3)

d-ph
d-ph

Reputation: 666

In case someone wants to make it JustWork(TM), do the following (worked in 2024):

version: '3.7'

x-configs:
  volumes:
    my-named-volume: &volume-my-named-volume 'my-named-volume:/whatever/path/i/need'
    my-other-named-volume: &volume-my-other-named-volume 'my-other-named-volume:/whatever/other/path/i/need'

services:
  myapp:
    image: myappimage
    # user: my-non-root-user
    volumes:
      - *volume-my-named-volume
      - *volume-my-other-named-volume

  fix-named-volumes-permissions:
    # the image doesn't matter; easiest to use the same as the target docker service
    image: myappimage
    user: root
    command: chmod 777 /whatever/path/i/need /whatever/other/path/i/need
    volumes:
      - *volume-my-named-volume
      - *volume-my-other-named-volume

volumes:
  my-named-volume:
  my-other-named-volume:

Every time you docker compose up -d, the permissions on the mounted named volumes will be corrected to 777 (still owned by root:root, though). Note that the "correction" needs to run merely once -- the 777 permissions are "persistent". In short: it JustWorks(TM) and it's a mystery why one has to use stackoverflow to get this done.

Upvotes: -2

KeaganFouche
KeaganFouche

Reputation: 681

I had a similar issue but mine was related to a file shared via a volume to a service I was not building with a Dockerfile, but pulling. I had shared a shell script that I used in docker-compose but when I executed it, did not have permission.

I resolved it by using chmod in the command of docker compose

command: -c "chmod a+x ./app/wait-for-it.sh && ./app/wait-for-it.sh -t 150 -h ..."
volumes:
    - ./wait-for-it.sh:/app/wait-for-it.sh

Upvotes: 0

Mafor
Mafor

Reputation: 10651

Yes, there is a trick. Not really in the docker-compose file, but in the Docker file. You need to create the /var/log/myapp folder and set its permissions before switching to the service user:

FROM ubuntu:18.04

RUN useradd myservice
RUN mkdir /var/log/myapp
RUN chown myservice:myservice /var/log/myapp

...

USER myservice:myservice

Docker-compose will preserve permissions.

See Docker Compose mounts named volumes as 'root' exclusively

Upvotes: 17

Related Questions