write in shared volumes docker

Docker

Docker Problem Overview


I have a docker with a php application on it

I have a share volume, for example

/home/me/dev/site <=> /var/www/site

I can write something in my host, it will be sync with the container

if I launch

sudo docker exec test touch /var/www/site/test.txt

It works

But if my server is trying to create a file as www-data this is not working because of the rights.

Is there a way to give access to my shared volumes to www-data ?

I am using boot2docker

Docker Solutions


Solution 1 - Docker

(Bind-mounted) volumes in Docker will maintain the permissions that are set on the Docker host itself. You can use this to set the permissions on those files and directories before using them in the container.

Some background;

Permissions in Linux are based on user and group ids ('uid' / 'gid'). Even though you see a user- and group name as owner, those names aren't actually important in Linux, they are only there to make it easier for you to see who's the owner of a file (they are looked up from the /etc/passwd file).

You can set any uid/gid on a file; a user doesn't have to exist when setting those permissions. For example;

touch foobar && sudo chown 1234:5678 foobar && ls -la foobar

# UID and GID are set to 1234 / 5678, even though there's no such user
-rw-rw-r-- 1 1234 5678 0 Mar 25 19:14 foobar

Checking permissions (inside and outside a container)

As mentioned above, Docker maintains ownership of the host when using a volume. This example shows that permissions and ownership in the volume are the same outside and inside a container;

# (First create a dummy site)

mkdir -p volume-example/site && cd volume-example
echo "<html><body>hello world</body></html>" > site/index.html

# Permissions on the Docker host;

ls -n site

# total 4
# -rw-rw-r-- 1 1002 1002 38 Mar 25 19:15 index.html

# And, permissions inside a nginx container, using it as volume;

sudo docker run --rm -v $(pwd)/site:/var/www nginx ls -n /var/www

# total 4
# -rw-rw-r-- 1 1002 1002 38 Mar 25 19:15 index.html

Setting the permissions

As explained, a user doesn't have to exist in order to use them, so even if we don't have a www-data user on the Docker host, we can still set the correct permissions if we know the "uid" and "gid" of that user inside the container;

Let's see what the uid and gid of the www-data user is inside the container;

sudo docker run --rm nginx id www-data

# uid=33(www-data) gid=33(www-data) groups=33(www-data)

First check the state before changing the permissions. This time we run the nginx container as user www-data;

sudo docker run \
  --rm \
  --volume $(pwd)/site:/var/www \
  --user www-data nginx touch /var/www/can-i-write.txt

# touch: cannot touch `/var/www/can-i-write.txt': Permission denied

Next, set the permissions on the local directory, and see if we are able to write;

sudo chown -R 33:33 site

sudo docker run \
   --rm \
   --volume $(pwd)/site:/var/www \
   --user www-data nginx touch /var/www/can-i-write.txt

Success!

Solution 2 - Docker

Add the following lines to your dockerfile and rebuild your image

RUN usermod -u 1000 www-data
RUN usermod -G staff www-data

Solution 3 - Docker

We are seeing a problem where php-fpm on Windows cannot write to files under /var/www/html, but Mac can. Kind of a variation on the original author's issue.

I am using Docker Desktop 4.4.2 on Mac Mojave (10.14.6). I have colleagues running Docker Desktop on Windows 10.

Our Docker container is using the php:7.1.33-fpm-alpine image.

We have a host folder mapped into the docker container at /var/www/html.

The www.conf under /usr/local/etc/php-fpm.d has the user, group, listen.user and listen.group all set to www-data.

On the Mac, php-fpm has no problem writing to the files under /var/www/html.

On Windows, php-fpm cannot write to the files under /var/www/html.

I observe something strange on the Mac. The ownership of files in the shared volume appear to change based upon the user I am logged into the container with.

If I log into the container with docker exec -it ideas-wordpress-1 /bin/sh and I list the files in /var/www/html with ls -l the files are all owned by root:root with the permissions rw-r--r--.

If I change the shell for the www-data user from /sbin/nologin to /bin/sh in /etc/passwd, and I su - www-data, when I list the files in the /var/www/html folder they are now owned by www-data:www-data with the permissions rw-r--r--.

On Windows, it's a little different.

If I log into the container with docker exec -it ideas-wordpress-1 /bin/sh and I list the files in /var/www/html with ls -l the files are all owned by root:root with the permissions -rwxrwxrwx.

If I change the shell for the www-data user from /sbin/nologin to /bin/sh in /etc/passwd, and I su - www-data, when I list the files in the /var/www/html folder they are now owned by root:root with the permissions -rwxrwxrwx. They didn't change.

I believe that this is why PHP-FPM can write to files in a mounted volume on Mac and not on Windows.

I wonder if we could get the Docker maintainers to modify docker for Windows to behave like it does on the Mac.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAjouveView Question on Stackoverflow
Solution 1 - DockerthaJeztahView Answer on Stackoverflow
Solution 2 - DockerIstván DöbrenteiView Answer on Stackoverflow
Solution 3 - DockerStephenKCView Answer on Stackoverflow