Modify a file which mount as a data volume but it didn't change in container

docker run -d -v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf nginx

After that I modified nginx.conf on docker host. However, I checked this file in container, it didn’t change.

I don’t know why, anyone can help me explain a little bit. I think the reason is permission .

My docker version is 1.6.2

Thank you in advance.

Greetings,

try updating to the latest and try

docker run -d -v /etc/nginx/nginx.conf:/etc/nginx/nginx.conf:rw nginx ?

HI @jeanepaul

Thank you for your reply. However, Your way didn’t fix my issue.
The issue is fixed if we change permission of file to 777.

Do you think it is a bug ?
I think docker permission is very difficult to understand.

Regards,
Khoa Nguyen.

Greetings,

@khoamisfit glad you made it. actually, your code really works(I’ve tested it few times), and I dont think it is a problem on docker side :smile:

@jeanepaul: Thank you so much. :). However, I want to understand why it is not working if we don’t change permission. Do you know the reason ? :smile:

Greetings,

afaik, when docker mounts dir/file, it maintain the ownership as the host. and if you are using docker-machine it tries to share /Users. in your case /etc/nginx/nginx.conf. it may have issues on permissions since ‘i suppose’ it’s outside your /Users

also in my test, i used dir in my /Users. when I tried using and mounting /etc/nginx, it never worked.

try using your /home/user instead?

That’s right. We can fix by work around. I knew this problem cause by permission.
But I still don’t understand clearly.

In the docker host:

ubuntu@ip-10-0-0-199:~$ ll /etc/nginx/nginx.conf
-rw-r–r-- 1 root root 2184 Apr 8 03:48 /etc/nginx/nginx.conf

the nginx file is owner by root . And it have read write permission,

When we mount this file into container, In the container,

root@b274abe902e1:/# ls -la /etc/nginx/nginx.conf
-rw-r–r-- 1 root root 2114 Aug 14 06:35 /etc/nginx/nginx.conf

As you see the permission are same.

If we change this file on docker host, the file is in container didn’t change as my problem.

However, if we change this file in container, the file on docker host also changed. That’s why I think it is a bug of docker.

Greetings,

I haven’t dig deeper yet, but I think it possess some security risk. I guess nobody would want to expose their system dir to containers.

still the best would be, mount dir/file from your /home and do whatever you want, rather than mounting from your system dir.

@khoamisfit can you share what is your host os version, your container image or container os, include uname -a result and your docker version? and result of stat /etc/nginx/nginx.conf on both?
thanks

@dolphyvn:
os host: ubuntu 14.04 .
uname -a: Linux ip-10-0-0-199 3.13.0-36-generic #63-Ubuntu SMP Wed Sep 3 21:30:07 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Container image: nginx

docker host
ubuntu@ip-10-0-0-199:~$ stat /etc/nginx/nginx.conf
File: ‘/etc/nginx/nginx.conf’
Size: 2115 Blocks: 8 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 459412 Links: 1
Access: (0644/-rw-r–r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-08-14 06:40:43.183774719 +0000
Modify: 2015-08-14 06:40:37.899774719 +0000
Change: 2015-08-14 06:40:37.935774719 +0000
Birth: -

In container:
root@7b1eb441124e:/# stat /etc/nginx/nginx.conf
File: '/etc/nginx/nginx.conf’
Size: 2115 Blocks: 8 IO Block: 4096 regular file
Device: ca01h/51713d Inode: 459412 Links: 0
Access: (0644/-rw-r–r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2015-08-14 16:24:51.567774719 +0000
Modify: 2015-08-14 06:40:37.899774719 +0000
Change: 2015-08-14 16:24:33.947774719 +0000
Birth: -

ubuntu@ip-10-0-0-199:~$ docker version
Client version: 1.5.0
Client API version: 1.17
Go version (client): go1.4.1
Git commit (client): a8a31ef
OS/Arch (client): linux/amd64
Server version: 1.5.0
Server API version: 1.17
Go version (server): go1.4.1
Git commit (server): a8a31ef

ubuntu@ip-10-0-0-199:~$ docker info
Containers: 4
Images: 460
Storage Driver: aufs
Root Dir: /var/lib/docker/aufs
Backing Filesystem: extfs
Dirs: 468
Execution Driver: native-0.2
Kernel Version: 3.13.0-36-generic
Operating System: Ubuntu 14.04.1 LTS
CPUs: 1
Total Memory: 1.954 GiB
Name: ip-10-0-0-199
ID: FEMB:X6ES:JD7L:AZN2:WEV7:VS4T:QIZU:YKEL:OXZI:R2RL:TJZN:OBPH
WARNING: No swap limit support

@khoamisfit can you try to reproduce the problem again on your env?
When you first start your container, try to append something to nginx.conf echo "##for test## >> /etc/nginx/nginx.conf" for example, not use vim insert mode on docker host. then check if it is synced on container ( keep file mode 644 )?

@khoamisfit Hi Khoa, also can you try to add set backupcopy=yes in your ~/.vimrc and still keep file mode 644. I believe it will fix the problem.

@dolphyvn: Yes, you’re right. If we use echo “xxx” >> /etc/nginx/nginx.conf , the changed is synced in container. So the vim insert mode change permission ? That’s why it is not synced in container . Can you explain more ?

@khoamisfit : I still confusing about the effected of permission mode on file. But Im think im closely to figure out why. Let me explain more :

Most of filesystem does not provide any kind of synchronization among I/O operations issued by the process on the same file, but as I remember there are system calls such as flock() are available to allow process to synchronize themselves on the entire of file or piece of it. So here is what Im trying to imagine, when you mount a file on docker host to container with mode 644, and try to append new content to it, it changed on both side, at this state, if you check stat on both side, the inode number is not change, but after that, if you use vim insert mode to modify the file on docker host, the file will not change on container, at this state if you try to compare inode again, the inode of the file on the docker host changed, but on the container, it stay the same. Then if you try to change the file permission to 664 (rw-rw-r) it synced on both. So let go back to what I describe aboved, if the file mode is 664 or group/other have permission to rw, the inode number will not change when you modify a file, and it synced to both side.
The set backupcopy=yes will force vim to reuse existing inode number instead of create new one.
I hope you get my idea right? inode not change --> file synced | inode changed --> file not synced

This might be involved into how linux handle file and depends on per filesystem.
When ever a process modifying a file, which will involve a system call mmap ( find out more with man mmap)

man mmap
mmap()  creates  a new mapping in the virtual address space of the calling process.  The starting address for the new mapping is specified
       in addr.  The length argument specifies the length of the mapping.

       If addr is NULL, then the kernel chooses the address at which to create the mapping; this is the most portable method of  creating  a  new
       mapping.   If addr is not NULL, then the kernel takes it as a hint about where to place the mapping; on Linux, the mapping will be created
       at a nearby page boundary.  The address of the new mapping is returned as the result of the call.

       The contents of a file mapping (as opposed to an anonymous mapping; see MAP_ANONYMOUS below), are initialized using length bytes  starting
       at  offset  offset  in  the  file  (or other object) referred to by the file descriptor fd.  offset must be a multiple of the page size as
       returned by sysconf(_SC_PAGE_SIZE).

You can use strace to dig more on each state of file mode, I did some strace to debug but forgot to save some of it to put it here so we can easy to compare, but ideally, whenever inode not change, the mapping address are the same, if inode changes, the mapping address also change.
When a process read a file its first look in the file descriptor ( fd contain all the informations of a file, included inode, check more on http://www.bottomupcs.com/file_descriptors.html ). So I guess when the inode on docker host change, the mapping address also change, but on the container is not, so it still point to the old version object mapped of the file. Will try to dig deeper

But still, I wont get why file permission effected to this. Maybe someone with more experiences on linux can explain.

1 Like

@dolphyvn: Thank you for your explanation. that makes sense .

When we changed permission of the file ( 777 or 664 ) , the inode is not be changed although we use vim to edit .

So the inode changed is root cause of this problem.

Again, thank you so much. :smile:

Thanks,you saved my day!