Docker volumes : specifying permissions using mount options
Asked Answered
A

2

18

I'm trying to use a named volume mounted in a Docker container, but get a Permission denied error when trying to create a file in the mounted folder. So I'm trying to use mount options when creating my volume, but that does not work as I want.

Introduction

I'm totally aware that when mounting a volume (created by docker volume create my_named_volume) with the option -v my_named_volume:/home/user/test or --mount type=volume,source=my_named_volume,target=/home/user/test), the folder inside the container (/home/user/test will be owned by root user, even if /home/user belongs to an user user created in my Dockerfile. If I run :

docker run --rm \
    --name test_named_volume \
    --mount type=volume,source=my_named_volume,target=/home/user/test \
    test_named_volume \
    su user -c "touch /home/user/test/a"

Then I get :

touch: cannot touch '/home/user/test/a': Permission denied

I'm understanding that. That's why I'm trying to use mount options when creating my volume.

mount options

I'm specifying an uid when creating my volume, in order to make my user user able to create a file in that volume :

docker volume create my_named_volume \
    --opt o=uid=1000

1000 is the uid of the user user created in my Dockerfile :

FROM    debian:jessie

ENV     HOME /home/user

RUN     useradd \
            --create-home \
            --home-dir $HOME \
            --uid 1000 \
            user \
 &&     chown -R user:user $HOME

WORKDIR $HOME

But when running my container (with the same command docker run defined above), I'm getting an error (missing device in volume options) :

docker: Error response from daemon: error while mounting volume '/var/lib/docker/volumes/my_named_volume/_data': missing device in volume options.

From the docs, I see that options --device and --type are missing from my volume creation :

docker volume create my_named_volume \
    --opt device=??? \
    --opt type=??? \
    --opt o=uid=1000

But I cannot see why I must give these options. device needs to be a block device, and from what I read, type should be something like ext4. But what I want is basically just set the uid option to my volume. It looks like creating a block device should work, but it seems too much configuration for a "simple" problem.

I have tried to use tmpfs for device and type, that works fine (file /home/user/test/a is created)... until my container is stopped (the data is not persisted, and that's logical because it's tmpfs). I want to persist that data written in the volume when the container exits.

What is the simplest way to specify permissions when mounting a named volume in a container? I don't want to modify my Dockerfile to use some magic (entrypoint that chown and then execute the command for example). It seems possible using mount options, I feel like I'm close to the solution, but maybe I'm in the wrong way.

Adapa answered 21/7, 2018 at 13:37 Comment(1)
I think this can be of solution to you, can you please try?Likker
B
2

Not entirely sure what your issue is, but this worked for me:

docker run --name test_named_volume \
  --mount type=volume,source=test_vol,target=/home/user \
  --user user \
  test_named_volume touch /home/user/a

I think where you could have gone wrong is:

  1. Your mount target is /home/user/test has not been created yet, since the useradd command in your Dockerfile only creates $HOME (/home/user). So docker creates the directory within the container with root permissions.

  2. You were not using the --user flag in docker run to run the container as the specified user.

Balkin answered 23/7, 2018 at 4:6 Comment(4)
Unfortunately, I really need to mount the volume on a folder that does not exist yet in the container (/home/user/test). My use-case is a little bit more complicated than the provided example. Actually, the test folder is a config folder (.config), and the entrypoint is an executable run by user (su user -c <executable>), storing data in that .config folder. But basically it's the same problem I explained, I hope that gives a little more context about my issue.Adapa
In that case you can address this in two ways - create the folder beforehand in the Dockerfile, or change permissions on the parent directory which you know will exist (/home/user/) in the Dockerfile and mount this directory instead.Balkin
As I said in the last paragraph, modifying the Dockerfile is not a suitable solution. Mounting the /home/user directory to one volume surely works, but potentially I could have multiple folders in that directory and want to mount different directories (/home/user/test1, /home/user/test2, ...) on different volumes. That's why I tried to use mount options instead of these solutions.Adapa
I came across the same problem and cannot find a solution. Setting a permission to a newly created mount point in docker config is like "1+1=2" in math. There a lot of people with this problem and I have no idea why this is not supported since version 1.Bifoliate
S
2

Just had this issue. And contrary to popular belief the mount did NOT pickup the permissions of the host mounted directory, it reset them.

When I did this, the permissions were changed to 777 inside the container...


volumes:
    - ./astro-nginx-php7/logs:/home/webowner/zos/log:rw

The :rw made all the difference for me. My image was nginx:latest. Docker compose version 3.3

Sacerdotalism answered 14/11, 2021 at 14:28 Comment(2)
I can't reproduce this. Maybe you're running docker-for-mac which might have different volume permissions behavior.Itu
This worked for me as well, also on Docker for Mac.Turnbull

© 2022 - 2024 — McMap. All rights reserved.