72
version: '2'
services:
    web:
        build:
            context: ./
            dockerfile: deploy/web.docker
        volumes:
            - ./:/var/www
        ports:
            - "8080:80"
        links:
            - app

How can I change permission (chmod) /var/www automatically when docker-compose up -d --build?

Pang
  • 9,564
  • 146
  • 81
  • 122
notalentgeek
  • 4,939
  • 11
  • 34
  • 53

3 Answers3

69

When bind-mounting a directory from the host in a container, files and directories maintain the permissions they have on the host. This is by design: when using a bind-mount, you're giving the container access to existing files from the host, and Docker won't make modifications to those files; doing so would be very dangerous (for example, bind-mounting your home-directory would change file permissions of your host's home directory, possibly leading to your machine no longer being usable).

To change permissions of those files, change their permissions on the host.

You can find more information on this in another answer I posted on StackOverflow: https://stackoverflow.com/a/29251160/1811501

thaJeztah
  • 27,738
  • 9
  • 73
  • 92
  • 19
    Dude... That's exactly what Docker is currently doing to me... It changes the permissions and the paths become accessible only by root or the docker container user... The rest of the apps cannot use the directory anymore. I am looking for a way to set the permissions so that I can set the permissions back to the ones I wanted to have before they get changed... This is incredibly annoying and breaks stuff! – Arturas M Nov 23 '20 at 19:05
  • How about if a `VOLUME` was created w/ `docker volume create --driver local ...`. Will it not be bind-mounted as well and if so, does one have control over file modes on the level of tools such as `docker volume` (as opposed to `docker volume inspect ... && chmod ...`)? – rookie099 May 12 '23 at 14:32
  • @ArturasM docker itself does not change the permissions, but the container runs as `root` and modifies file-permissions (or creates files), those files may be owned by `root`. If those files are in a bind-mounted directory, then those files are modified. Run your container as a non-root user (which can be the UID/GID matching your user-account), or you can run the Docker Engine in "rootless mode" and set it up to re-map the `root` user to your account. https://docs.docker.com/go/rootless/. Alternatively, use Docker Desktop, which converts permission (but comes with a performance overhead) – thaJeztah Jun 03 '23 at 13:21
  • @rookie099 a `VOLUME` is effectively also a bind-mount, but the path that's mounted from is (by default) in a dedicated location on the daemon's host (inside `/var/lib/docker`); those files should not be accessed directly from other tools. You can create a volume with a custom "source" location, but the situation is mostly the same (permissions in container === permissions "on the host"). – thaJeztah Jun 03 '23 at 13:23
  • 1
    I should add that recent versions of the Linux kernel added support for idmapped mounts, which could improve this in future (but it's not supported by all kernels, and support for it has not yet been implemented in all components used to run containers). – thaJeztah Jun 03 '23 at 13:24
  • I had to clean up my volumes and rebuild them. I had a previous volume for the same name that wasn't the local directory that I wanted to mount. After deleting the old volume and running my docker-compose file again, it works. – Code-Apprentice Jun 17 '23 at 20:02
17

you can add the permissions after an extra column like:

    volumes:
            - ./:/var/www:ro #read only
SuperPoney
  • 563
  • 6
  • 21
Edwin
  • 2,146
  • 20
  • 26
  • 3
    Let say I want to have 777 or 750 like permission what would `ro` be? – notalentgeek May 14 '18 at 08:08
  • 2
    check this out https://en.wikipedia.org/wiki/Chmod, especially the @Numerical permissions – Edwin May 14 '18 at 08:09
  • 4
    wait a second, you want to change the permissions of the files and folders of the mounted volume? I miss-read your question then, because that you can do it only on the host – Edwin May 14 '18 at 08:20
  • 1
    Just remember to delete the "//read only" part or you will get confusing errors about "invalid mode" when building – Vidde Jul 08 '21 at 08:42
  • 1
    This will mount a read-only filesystem, which isn't quite the same thing as changing permissions. It doesn't impact the flags set by chmod – CantankerousBullMoose May 12 '22 at 17:48
8

Actually this is a little more complicated, some better clarity would be required.

If we mount the host folder folder_a into guest folder folder_b and the folder_b was already created, "chown"-ed and "chmod"-ed when the container image was created (Dockerfile), then folder_b defined permissions must take precedence from the guest perspective. This is what is happening on my boxes. As the guest user is not supposed to exist in the host an answer like "add the permissions to the host" is not very beautiful, it would mean "give write permissions to everybody".

If folder_b was not already "prepared" for the mount upfront, but it is mounted "on the fly"; I have not found any way to change the permissions contextually. Trying to reason out loud: the docker daemon on the host does not know anything about the guest users. I am also curious if a chmod/chown on the fly with guest names is technically possible as an evolution of docker. My initial expectation is that the on the fly mount inherited the parent folder permissions ( if /mnt/a is owned by app_user, then mounting in /mnt/a/myMount would preserve app_user ownership to the child folder as well, however, the new mounted folder is owned by root in my tests )

From a security perspective, the guest operating the mounts should never mount its own secured/sensitive folders to the guests. It is generally assumed that if you give a volume to a guest, the guest must be able to execute any operation on it. However mounting "on the fly" produces a "root" owned folder inside the guest as root is the only user known to both guest and host.

  • 1
    You can pass the (current) user (and group) to docker, like it is described in this article: Running a Docker container as a non-root user -> https://medium.com/redbubble/running-a-docker-container-as-a-non-root-user-7d2e00f8ee15 – leonp5 May 05 '22 at 09:01