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

2

17

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?

Mccormack answered 11/8, 2017 at 13:3 Comment(6)
Is /c/Users/tom/projects/myproject/data/var/www/public/config.inc.php a file or a folder?Murraymurre
config.inc.php is a fileMccormack
but it doesn't matter whether I mount folders or files as volumes, I am not able to change the permissionsMccormack
found another link with the same issue: forums.docker.com/t/…Monamonachal
You might want to try mounting the parent directory instead of the single file. Changing permissions on a mount point could be something special (say: impossible).Monamonachal
@Monamonachal I tried both already. I did some research and it's probably related to the inherently different permission models of nfts and ext3 since I am trying to mount a folder/file from my windows host into a debian container. My current workaround for persisting my config is to push it to a docker data volume and mount that instead.Mccormack
M
10

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.

Merciless answered 16/8, 2017 at 3:54 Comment(18)
this approach looks promising. I'll try it and get back to you, thank youMccormack
wait, I can't hardlink on my host OS since it's windows. Did I misunderstand you?Mccormack
This was for linux OS, for windows you can use mklink. More details hereMerciless
so basically I create a hardlink from my windows host into a datavolume and mount that volume in my container?Mccormack
That is exactly what I am trying to do. I'll update the detailed steps in my answer.Merciless
mklink /h /d '/mnt/sda1/var/lib/docker/volumes/myproject_data-volume/_data/config.inc.php' \Users\tom\projects\myproject\data\var\www\public\config.inc.php returns "invalid Option - "mnt" on cmd.Mccormack
I also tried for /f "usebackq tokens=*" %i in (docker volume inspect --format '{{.Mountpoint}}' "myproject_data-volume/config.inc.php") do mklink /h /d %i \Users\tom\projects\myproject\mydata\config.inc.php which did not work either.Mccormack
I have created a data-volume containing a file beforehand but the docker volume inspect command returns a unix path.Mccormack
well, combining /h and /d in mklink is not supposed to work together anyways but even with valid syntax I can't hardlink a unixpath to a windowspathMccormack
Ah, I found that volume path on windows and mac is different than the actual path shown by volume inspectMerciless
Path in windows is C:\Users\Public\Documents\Hyper-V\VirtualMerciless
I'm not using Hyper-V but virtualbox driver and docker-machine. Is there still a chance to get this working somehow?Mccormack
If you can update your question with the details of the process, then maybe we could look for another approach. Might be that your files are accessible in some other way.Merciless
what process exactly?Mccormack
I am not sure about virtual-box driver, are you running the containers in virtual box? The process I wanna know about is that how you are accessing real files on host and how your docker is running. More relevant part would be, where your docker is storing its files?Merciless
are you okay with me moving this discussion to the chat?Mccormack
Let us continue this discussion in chat.Merciless
A hard link can't cross file system boundaries so this wouldn't work for file shared from Windows > LinuxPellagra
G
8

Try one of the following:

  1. If you can rebuild the image image: image: (secrect company registry)/docker-stretchimal-apache2-php7-pma then inside the docker file, add the following

    USER root RUN chmod 655 config.inc.php

Then you can rebuild the image and push it to the registry, and what you were doing should work. This should be your preferred solution, as you don't want to be manually changing the permissions everytime you start a new container

  1. Try to exec using the user root explicitly

    docker exec -it -u root [container] bash

Graphemics answered 14/8, 2017 at 8:6 Comment(4)
I am unable to change permissions of directories/volumes mounted from windows host into docker container. AFAIK, 1. will chmod the confic.inc.php inside the image which will get overridden by my mounted confic.inc.php. 2. does not work. Even if I -u root, the permissions still won't change when I chmod.Mccormack
@TomM can you provide the docker file for the image?Graphemics
no, sorry. But it does not work with images from the official registry either so I doubt the image is at faultMccormack
Dockerfile is executed (built) before volume is mounted, you can't change permissions in mounted volume this way.Galingale

© 2022 - 2024 — McMap. All rights reserved.