13

I have Docker container with named volume running on non-root user started with the following command:

docker run -v backup:/backup someimage

In the image, there's a backup script which is trying to save files in /backup directory but it fails. Mounted backup volume in /backup dir belongs to root user.

How to change permissions for /backup directory?

-----EDIT1:

mcve below:

Run docker container with Gerrit:

docker run -v backupgerrit:/backup --name gerrit gerritcodereview/gerrit

Now on other terminal window try to save something in /backup dir:

docker exec gerrit touch /backup/testfile

You will get:

touch: cannot touch '/backup/testfile': Permission denied

2 Answers 2

27

Named volumes are initialized when first created to the contents of the image at the mount location. That initialization includes the owner and permissions. If /backup does not exist in your image, then an empty directory will be created and owned by root. You can:

Option 1: Create the directory in your Dockerfile with the appropriate ownership and permissions:

FROM your-image
USER root
RUN mkdir -p /backup \
 && chown -R your-user /backup
USER your-user

Note, this only works when the backup named volume does not already exist or is empty. And it needs to be a named volume, not a host volume.

Option 2: Initialize the named volume, including some content inside the volume (an empty file would work) using another temporary container:

docker run --rm -v backupgerrit:/backup busybox \
  /bin/sh -c 'touch /backup/.initialized && chown -R 1000:1000 /backup'

Option 3: Adjust the permissions after the volume is mounted, requiring root inside your container:

docker exec -u 0:0 your-container chown -R your-user /backup
10
  • 1
    I tested the first solution and it doesn't work. I created /backup dir in Dockerfile, changed ownership to id=1000 but after containter start it is still root ownership. How to initialize named volume with empty file? You mean doing it before starting container? For now I'm using third solution. Backup script is triggered by docker exec -u root... command.
    – QkiZ
    Sep 18, 2019 at 9:15
  • @qkiz please provide a mcve. In particular, something like a volume defined inside your Dockerfile could break things. Or trying to initialize a volume that already exists.
    – BMitch
    Sep 18, 2019 at 10:10
  • question updated
    – QkiZ
    Sep 18, 2019 at 15:02
  • 2
    It is minimal in configuration. Dockerfile is not needed because you can use image from Docker Hub. backup dir isn't needed in image. It will be created by Docker at container start if you use docker run command from example.
    – QkiZ
    Sep 19, 2019 at 6:19
  • 1
    Did you read first comment?
    – QkiZ
    Feb 25, 2021 at 11:14
0

Working solution here. Docker on default settings keeps volumes data in /var/lib/docker/volumes/. Basing on example from question files of backupgerrit named volume are keep in /var/lib/docker/volumes/backupgerrit/_data. Essential dir is _data and its permissions. In this example, Gerrit container uses a user with id 1000. The solution is to set ownership of this _data dir to 1000:1000.

# chown 1000:1000 /var/lib/docker/volumes/backupgerrit/_data
# ls -ln /var/lib/docker/volumes/backupgerrit/
drwxr-xr-x 2 1000 1000 4096 Feb 25 12:19 _data/

And this is how it looks from container side:

# docker ps
CONTAINER ID   IMAGE                     COMMAND            CREATED          STATUS          PORTS                 NAMES
eaa816980be5   gerritcodereview/gerrit   "/entrypoint.sh"   31 minutes ago   Up 31 minutes   8080/tcp, 29418/tcp   gerrit
# docker exec gerrit id
uid=1000(gerrit) gid=1000(gerrit) groups=1000(gerrit)
# docker exec gerrit ls -l / | grep backup
drwxr-xr-x   2 gerrit gerrit 4096 Feb 25 11:19 backup
# docker exec gerrit touch /backup/testfile
# docker exec gerrit ls -l /backup
total 0
-rw-r--r-- 1 gerrit gerrit 0 Feb 25 11:19 testfile

Permissions of _data dir are persistent till removing volume with

# docker volume rm backupgerrit
1
  • 2
    This isn't portable since it relies on the underlying file structure of the internal docker directories, and also won't work if you alter any of the settings of the named volume, e.g. to use NFS. This would be better done with a temporary container that mounts the volume the same as docker mounts it in all other containers, abstracting away these docker internals.
    – BMitch
    Feb 25, 2021 at 14:04

You must log in to answer this question.

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