Docker-compose set user and group on mounted volume

Solution 1:

To achieve the desired behavior without changing owner / permissions on the host system do the following steps.

  1. get the ID of the desired user and or group you want the permissions to match with executing the id command on your host system - this will show you the uid and gid of your current user and as well all IDs from all groups the user is in.

     $ id
    
  2. add the definition to your docker-compose.yml

     user: "${UID}:${GID}"
    

    so your file could look like this

     php: # this is my service name
         user: "${UID}:${GID}" # we added this line to get a specific user / group id
         image: php:7.3-fpm-alpine # this is my image
     # and so on
    
  3. set the values in your .env file

     UID=1000
     GID=1001
    

Now your user in the container has the id 1000 and the group is 1001 and you can set that differently for every environment.

Note: Please replace the IDs I used with the user / group IDs you found on your host system. Since I cannot know which IDs your system is using I gave some example group and user IDs.

If you don't use docker-compose or want to know more different approaches to achieve this have a read through my source of information: https://dev.to/acro5piano/specifying-user-and-group-in-docker-i2e

Solution 2:

The bad news is there's no owner/group/permission settings for volume 😢. The good news is the following trick will let you bake it into your config, so it's fully automated 🎉.

In your Dockerfile, create an empty directory in the right location and with desired settings.

This way, the directory will already be present when docker-compose mounts to the location. When the server mounts during boot (based on docker-compose), the mounting action happily leaves those permissions alone.

Dockerfile:

# setup folder before switching to user
RUN mkdir /volume_data
RUN chown postgres:postgres /volume_data
USER postgres

docker-compose.yml

volumes:
   - /home/me/postgres_data:/volume_data

source

Solution 3:

First determine the uid of the www-data user:

$ docker exec DOCKER_CONTAINER_ID id
uid=100(www-data) gid=101(www-data) groups=101(www-data)

Then, on your docker host, change the owner of the mounted directory using the uid (100 in this example):

chown -R 100 ./

Dynamic Extension

If you are using docker-compose you may as well go for it like this:

$ docker-compose exec SERVICE_NAME id
uid=100(www-data) gid=101(www-data) groups=101(www-data)
$ chown -R 100 ./

You can put that in a one-liner:

$ chown -R $(docker-compose exec SERVICE_NAME id -u) ./

The -u flag will only print the uid to stdout.

Edit: fixed casing error of CLI flag. Thanks @jcalfee314!

Solution 4:

Adding rw to the end of the volume mount worked for me:

services:
    httpd:
        image: apache-image
        ports:
            - "80:80"
        volumes:
            - "./:/var/www/app:rw"
        links:
            - redis
        command: /setupApacheRights.sh