PHP
PhpStorm
docker
dockerformac

Docker for Mac に潜む罠? ファイル名の大文字・小文字の区別

More than 1 year has passed since last update.

(先日投稿した内容に誤りがあったので、修正しての再投稿です。)

実はよく分かってないので、走り書き程度となりますが、Docker for MacでPHPアプリの開発を進めていて罠にはまったかもしれないので、ここに書いておきます。

英語が分かる人はたぶんこっちを読んだ方が早いです。
https://docs.docker.com/docker-for-mac/osxfs/

Case sensitivity

With Docker for Mac, file systems are shared from OS X into containers in the same way as they operate in OS X. As a result, if a file system on OS X is case-insensitive that behavior is shared by any bind mount from OS X into a container. The default OS X file system is HFS+ and, during installation, it is installed as case-insensitive by default. To get case-sensitive behavior from your bind mounts, you must either create and format a ramdisk or external volume as HFS+ with case-sensitivity or reformat your OS root partition with HFS+ with case-sensitivity. We do not recommend reformatting your root partition as some Mac software dubiously relies on case-insensitivity to function.

コンテナ内のPHPで大文字・小文字の区別周りで謎の挙動

CentOS7をベースにしたPHPが組み込まれているコンテナを使ってPHPアプリケーションの開発をしていたところ、一緒に開発している仲間から「とあるクラスが無い」というエラーが出るという報告がありました。調べたところ、クラス名の表記が大文字と小文字で間違っていました。ただ、私の環境では問題なく動きます。その方はCentOS7上で直接開発していたのですが、私もCentOS7ベースのコンテナを使って開発していたので???でした。

でも当然ながらピュアなCentOSの挙動が正しいと思いますし、これはDocker for Mac側に罠が潜んでいると察しました。このままだとDocker for MacでPHPの開発しても大文字、小文字のミスが発見できないのでとても危険!!!!

キャー、怖い!!!

原因を調査する

PHPでは通常はクラス名の大文字・小文字は区別しないようなので、ここは直接の原因ではなく(間接的にはからんでそうですが)、おそらくファイルシステムの方に原因があるのではないか?と考え、コンテナ内で色々コマンドを叩いてみました。

# df -T

大文字小文字チェック1.png

aufs??? osxfs???? ふーん。よく分からん。

PHPのソースコードを置いてあるのは /var/www 以下なので ext4 じゃないのか?

/var/www 以下の領域で以下をためす

# touch test.txt
# touch Test.txt
# ls -al

名称未設定.png

あちゃー、大文字と小文字を区別してないー 良くわかんねーな… 
OSXからも見えるようにdocker-composeのvolume機能でマウントしてる(File system sharing)のが影響してそうな気はします。(要検証)

手っ取り早く解決する

開発は佳境。かといって、この状況を放置するのも怖いので手っ取り早くさくっと対応したい。

当てずっぽうですが、デフォルトでは大文字、小文字を区別しないMacのファイルシステムHFS+が影響していると決めつけて、別論理ボリュームを新しく切って、大文字、小文字を区別できるようにフォーマットにしました。

大文字小文字チェック2.png

どうでも良いですが、「CS」は「Case Sensitive」の略です。

PHP上でエラーが出なかった方の論理ボリュームからそのままファイルまるっとをコピーして同様にコンテナを立ち上げて確認したところ…

# touch test.txt
# touch Test.txt
# ls -al

名称未設定.png

うん、ちゃんと二つファイルがある。

PHPでエラーが出なかったところを確認すると…、

名称未設定.png

一部マスクをかけてあり見にくいですが、「クラスがありません」というエラーが正しく出ました。

これで安心してPHPのクラス名で大文字、小文字を間違えられる!!!

※注意

そんな人いないとは思いますが、Macのシステムがあるボリュームで大文字、小文字を区別するフォーマットにするのはおそらく危険ですのでやめましょう。少なくともAdobeのソフトウェアはサポートしてないようです。

「大文字と小文字が区別されるドライブへのインストールはサポートされていません」エラー
https://helpx.adobe.com/jp/creative-suite/kb/cq05121953.html

結論

Docker for Mac を使う場合はファイルの大文字、小文字問題に注意せよ!! 安全に利用するにはホスト側の論理ボリュームが大文字、小文字を区別できる環境で利用するべし

もう少しスマートな解決方法をご存じの方は教えて頂きたいです。

ただ、大文字、小文字を区別する論理ボリュームで開発した方が間違いは起きにくい気がしますし、本番環境がLinuxであればその環境に近づけることになります。これといったデメリットもないと思うので、気になる方はやっておいて損はないかと思います。

おまけ

大文字、小文字を区別するようにしたとたん、PHP Stormを起動した瞬間にエラー吐くようになった…

idea.case.sensitive.fs=true

にせよ、と。

Android Studioで"Filesystem Case-Sensitivity Mismatch"エラーを回避する
http://qiita.com/kinneko/items/7f8a4292377e0164e9cf

をヒントに解決させた。

$ echo "idea.case.sensitive.fs=true" > mac-idea.properties
$ mv mac-idea.properties ~/Library/Preferences/PhpStorm2016.3/idea.properties

だけです。