dockerdocker-composedocker-machinedocker-toolboxdocker-for-windows

Change file permissions in mounted folder inside docker container on Windows Host


Disclaimer/Edit 3

In my opinion, the best approach nowadays is using Docker in WSL. You might only get issues with for example file watchers and permissions if you're working in a path that was mounted from your host, so to make sure everything is as compatible as possible, don't work in /mnt/c/ and instead use a native folder in your WSL FS.

Disclaimer/Edit 2

Some years later, for everyone reading this question - If you are on Windows and want to use docker with linux containers, I highly recommend not using docker for windows at all and instead starting the entire docker environment inside a VM altogether. This Ext3 NTFS issue will break your neck on so many different levels that installing docker-machine might not even be worth the effort.


Edit:

I am using docker-machine which starts a boot2docker instance inside a Virtualbox VM with a shared folder on /c/Users from which you can mount volumes into your containers. The permissions of said volumes are the ones the question is about. The VMs are stored under /c/Users/tom/.docker/

I chose to use the docker-machine Virtualbox workflow over Hyper-V because I need VBox in my daily workflow and running Hyper-V and Virtualbox together on one system is not possible due to incompabilities between different Hypervisors.

Original question

I am currently trying to set up PHPMyAdmin in a container on windows but I can't change the permissions of the config.inc.php file.

I found: Cannot call chown inside Docker container (Docker for Windows) and thought this might be somewhat related but it appears to apply only to MongoDB.

This is my docker-compose.yml

    version: "3"

    services:
      pma:
        image: (secrect company registry)/phpmyadmin
        ports: 
          - 9090:80
        volumes:
          - /c/Users/tom/projects/myproject/data/var/www/public/config.inc.php:/var/www/public/config.inc.php

now, when I docker exec -it [container] bash and change in the mounted directory, I try to run chmod on the config.inc.php but for some reason, it fails silently.

root@22a4bag43245: ls -la config.inc.php
-rw------- 1 root root 0 Aug 11 15:11 config.inc.php
root@22a4bag43245: chmod 655 config.inc.php
root@22a4bag43245: ls -la config.inc.php
-rw------- 1 root root 0 Aug 11 15:11 config.inc.php

Considering the linked answer, I thought I could just move the volume out of my Userhome but then vbox doesn't mount the folder at all.

How do I change the file permissions of /var/www/public/config.inc.php persistently?


Solution

  • I had the same problem of not being able to change ownership even after using chown. And as I researched, it was because of NTFS volumes being mounted inside ext filesystem. So I used another approach.

    The volumes internal to docker are free from these problems. So you can mount your file on internal docker volume and then create a hard symlink to that file inside your local folder wherever you want:

    sudo ln $(docker volume inspect --format '{{ .Mountpoint }}' <project_name>_<volume_name>) <absolute_path_of_destination>
    

    This way you can have your files in desired place, inside docker and without any permission issues, and you will be able to modify the contents of file as in the normal volume mount due to hard symlink.

    Here is a working implementation of this process which mounts and links a directory. In case you wanna know about the details, see possible fix section in issue.

    EDIT

    Steps to implement this approach:

    1. Mount the concerned file in internal docker-volume(also known as named volumes).
    2. Before making hardlink, make sure volumes and concerned file are present there. To ensure this, you should have run your container at least once before or if you want to automate this file creation, you can include a docker run which creates the required files and exits.

      docker run --rm -itd \ -v "<Project_name>_<volume_name>:/absolute/path" \ <image> bash -c "touch /absolute/path/<my_file>"

    This docker run will create volumes and required files. Here, container is my project name, by default, it is the name of the folder in which project is present and <volume_name> is the same as one which we want to use in our original container. <image> can be the same one which is already being used in your original containers.

    1. Create a hardlink in your OS to the actual file location on your system. You can find the file location using docker volume inspect --format '{{ .Mountpoint }}' <project_name>_<volume_name>/<my_file>. Linux users can use ln in terminal and windows users can use mklink in command prompt.

    In step 3 we have not used /absolute/path since the <volume_name> refers to that location already, and we just need to refer to the file.