docker-compose.yamlでmountしたファイルを更新しても、更新内容が反映されなかったために、原因調査の備忘録です。
困ったこと
docker-compose.yamlでmountしたファイルを更新しても、更新内容が反映されなかった。
※以下は、サンプルコードです。
service:
image: image-sample
container_name: "container-sample"
volumes:
- ./yamls/sample.yaml:/yamls/sample.yaml
原因
volumensでファイル指定をしていたために、ファイルの内容を変更後のファイル情報が変更されてしまうために変更後のファイルを参照できていなかった。
分かったこと
dockerでマウントしている時は、inodeと呼ばれるファイルに関するデータ構造を参照しているらしい。
そのため、ファイル内容を変更するとinode情報も変更されるために、変更前のファイル情報を参照してしまう。
▽原因説明してくれてるコメント
ここで何が起こっているか、私には分かるかもしれません…
もしvimのようなエディタを使っている場合、ファイルを保存するときに直接ファイルを保存するのではなく、新しいファイルを作成してその場にコピーします。これはinodeに基づいたバインドマウントを破壊します。ファイルを保存することは実質的にinodeを変更するため、変更はコンテナに伝搬しません。コンテナを再起動すると新しいinodeです。ファイルをその場で編集すれば、変更が伝搬するのを見ることができるはずです。
これはファイルマウントの既知の制限であり、修正は不可能です。
この説明は問題を正確に表していますか?
inodeを実際に確認
1.テストフォルダ作成
$ mkdir test-inode
2.inode情報確認
$ ls -ial
24968113 drwxr-xr-x 2 ryotaro staff 64 Mar 18 22:48 test-inode
3.フォルダに内移動
cd test-inode
4.ファイル作成
$ touch a.txt
5.inode情報確認
$ ls -ial
24968113 drwxr-xr-x 3 ryotaro staff 96 Mar 18 22:53 .
24968756 -rw-r--r-- 1 ryotaro staff 0 Mar 18 22:53 a.txt
6.ファイル内容変更後確認
inode情報が、24968756から24968973へ変更されているが、
現在のディレクトリのinode情報は変更されていないことが確認できる。
$ vim
$ ls -ial
24968113 drwxr-xr-x 3 ryotaro staff 96 Mar 18 22:54 .
24968973 -rw-r--r-- 1 ryotaro staff 2 Mar 18 22:54 a.txt
解決策
volumesの箇所を、ディレクトリ指定に変更することで、ディレクトリ内の変更内容が反映される。
service:
image: image-sample
container_name: "container-sample"
volumes:
- ./yamls:/yamls
これまでLinuxのファイルシステムを見る際には、主に権限設定に注目してきましたが、inodeという概念を知ることができて良かったです。この知識を直接使用する機会は少ないかもしれませんが、もっと多くを学んでいれば、問題の原因調査をより迅速に行えるようになるのではないかと思います。
参考資料
・Linuxの「inode」とは?概要や確認方法をご紹介
・File mount does not update with changes from host #15793