ついに平成が終わりますね。
せっかくなので以前から書こうと思っていた小ネタを置いておきますね。
問題遭遇
ある日、dockerを使って作業をしていると「単体ファイルをマウントしたとき、ホスト上(マウント元)のファイルを更新してもコンテナ内(マウント先)に反映されていない」ことに気づきました。これまでも同様の作業を行ったことはあるのですが、その際にはそのような現象は見られなかったのにです。
そのときは深く考えずにディレクトリマウントに変更して問題を回避して作業を続けたのですが、後日同じ問題に遭遇したので再度詳しく調査してみました。
その際に Stack Overflow では幾つか記事(こことかここ)も見つかるのですが、日本語ではパッと見無さそうだったので、調査した結果と対策をまとめてみます。
原因
docker 自体はシングルファイルのバインドマウントの更新をコンテナに反映します。公式のドキュメントでも特にこれについての制限は記載されていません。
今回の問題の原因はファイルの i-node にあります。シングルファイルをバインドマウントした場合、docker は対象ファイルの i-node を指してマウントします。このため、ホスト上のファイルの更新によって i-node が変更された場合、以降コンテナ内でその変更は反映されなくなるのです。
回避方法
根本原因は i-node ですので、i-node が変更されないようにすれば更新が反映されます。これを考慮にいれると問題を回避しつつ更新を反映する方法は以下の2つが考えられます。
- 編集対象のファイルを含むディレクトリをマウントする
- 編集時に i-node を変更しないようにする
以下、それぞれについて詳しく検討します。
ファイルを含むディレクトリをマウントする
最初に問題に遭遇した際にとった方法です。安直な対処法ですが、また同じ問題を(別の人が)踏んで戸惑う可能性があるのであれば、こちらの方法をとって回避するほうが望ましい場合があるかもしれません。
i-node を変更しないようにする
環境によって違いがあるのですが、自分がとった方法を列挙しておきます。
- 編集方法(例えば、エディタの保存方法)を変更する
エディタについて言えば、お使いのエディタのヘルプを参考にして i-node が変わらないような設定に変更してください。そのほかの場合も編集時に i-node が変わらない方法(例えばリダイレクトによる追加など)を取れば大丈夫です。
- ファイルパーミッションを変更する
本記事を書くために当該のページを探したところ見つからないのですが、Stack Overflow に記載があった方法を試してみたところ回避できたので記載しておきます。
その記事では、パーミッションが 644 のファイルをマウントしている場合にはこれを 664 に変更すると i-node が変更されなくなるためコンテナ内に変更が反映されるようになると書かれてありました。
確かに手元の Ubuntu 上での vim による編集では同様の挙動を示しており、実際に問題を回避できたのですが、このような挙動を取る詳しい理由までは調べきれていません。(ファイルシステムやエディタの設定によるようですが)
まとめ
忘れた頃に遭遇してあれっ?と思うので、他にも同じ様に引っかかる人の助けになれば幸いです。