Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind-Mount a single File with docker-compose

In my docker-compose (3.7) file I have something like

  - ./a/src/:/var/www/html/
  - ./a/config/local.php.ini:/usr/local/etc/php/conf.d/local.ini

as can be found for example in this example.

Whenever I change something on host in the ./a/src directory or in the container in /var/www/html/ it gets changed on the other side as expected. They are the same as they should be.

Not so with the file. It gets copied (I guess) to the container. But then, if I change local.php.ini on the host or /usr/local/etc/php/conf.d/local.ini the other one remains the same.

Is that the expected behavior? If yes, why and is it possible to change it so, both files are the same like with the directory

Note: This is not a duplicate of How to mount a single file in a volume. I get my file as file not as directory or such. I nevertheless tried it with absolute directories with ${PWD} as suggested there but that changed nothing.

Docker version 19.03.1, build 74b1e89
docker-compose version 1.24.1, build 4667896b

Host and container systems are Debian.

like image 495
Paflow Avatar asked Jan 01 '23 17:01

Paflow


1 Answers

Please go through this.

I guess it might have caused because of this reason.

If you edit the file using text editor like vim, when you save the file it does not save the file directly, rather it creates a new file and copies it into place. This breaks the bind-mount, which is based on inode. Since saving the file effectively changes the inode, changes will not propagate into the container. Restarting the container will pick up the new inode and changes will got reflected.

Here is an example, explaining what I mean:

# Create a file on host and list it contents and its inode number
-------------------
$ echo 'abc' > /root/file.txt
$ cat /root/file.txt 
abc
$ ls -ltrhi /root/
total 4K     
1623230 -rw-r--r--    1 root     root           4 Aug 23 17:44 file.txt
$
# Run an alpine container by mounting this file.txt
---------------------
$ docker run -itd -v /root/file.txt:/var/tmp/file.txt alpine sh
d59a2ad308d2de7dfbcf042439b295b27370e4014be94bc339f1c5c880bf205f
$
# Check file contents of file.txt and its inode number inside alpine container
$ docker exec -it d59a2ad308d2 sh
/ # cat /var/tmp/file.txt 
abc
/ # ls -ltrhi /var/tmp/
total 4K     
1623230 -rw-r--r--    1 root     root           4 Aug 23 17:44 file.txt
/ #

## NOTE: The inode number of file.txt is same here 1623230 on host and inside the container.

# Edit the file.txt inside alpine container using some text editor like vi
--------------------------
/ # vi /var/tmp/file.txt 
/ # ls -ltrhi /var/tmp/
total 4K     
1623230 -rw-r--r--    1 root     root           5 Aug 23 17:46 file.txt
/ # cat /var/tmp/file.txt 
abcd
/ #

# Check content of file.txt on host, it will be the same as the one inside container since the inode number of file.txt inside container and on host is still same 1623230 
--------------------------
$ cat /root/file.txt   <<=== ran it on host
abcd

# Now edit content of file.txt on host and check its inode number.
$ vi file.txt 
$ ls -ltrhi /root/
total 4K     
 862510 -rw-r--r--    1 root     root           6 Aug 23 17:47 file.txt
$ cat file.txt 
abcde
$ 

## NOTE: the inode number of file.txt on host is changed to 862510 after editing the file using vi editor.

# Check content of file.txt inside alpine container and list it inode number
----------------------------
$ docker exec -it d59a2ad308d2 sh
/ # ls -ltrhi /var/tmp/
total 4K     
1623230 -rw-r--r--    0 root     root           5 Aug 23 17:46 file.txt
/ # cat /var/tmp/file.txt 
abcd
/ #

## NOTE: inode number here is the old one and doesn't match with the one on the host and hence the content of file.txt also doesn't match.

# Restart alpine container
---------------------------
$ docker restart d59a2ad308d2
d59a2ad308d2
$ docker exec -it d59a2ad308d2 sh
/ # cat /var/tmp/file.txt 
abcde
/ # ls -ltrhi /var/tmp/
total 4K     
 862510 -rw-r--r--    1 root     root           6 Aug 23 17:47 file.txt
/ # [node1] (local) [email protected] ~
$ 

## NOTE: After restarting container, the inode of file.txt is matching with the one on host and so the file contents also match.

I also highly recommend you to go through this link, it has more info.

Hope this helps.

like image 95
mchawre Avatar answered Jan 05 '23 18:01

mchawre