以前 Docker 上での Laravel の処理が大変遅く、快適に使えていない現状を記事にしました。
この問題に対して、docker-compose.yml
を少し修正した結果、レスポンスが 3000ms(3 秒)から 200ms ~ 300ms(0.2 秒~ 0.3 秒)にまで削減することができました。
解決策は至って単純で、ライブラリをホストのディレクトリにマウントしないだけです。
Laravel だけではなく、Docker 上で開発すると多くの言語やフレームワークで同様の現象は発生しています。今回解決する上では Node 開発環境から node_modules をマウントから外すという記事を参考に、node_modules と vendor をマウントから外しました。
VSCode の Remote Development を使って Docker を起動する場合、.devcontainer
ディレクトリ配下に、Dockerfile
やdocker-compose.yml
を置くことが多く、docker-compose.yml
では、volumes を以下のように記載することがあります。
services:
node:
build: ./node
volumes:
- ../:/workspace:cached
これは Docker を起動し、VSCode がディレクトリを開く際に、.devcontainer
ディレクトリの 1 つ上の階層を指定し、それを Docker 上では/workspace
というディレクトリにマウントするという形になっています。
├─.devcontainer
└─src
└─node_modules
このとき、node_modules
だけをホストのディレクトリからマウントを外したければ以下のように書きます。
services:
node:
build: ./node
volumes:
- ../:/workspace:cached
- /workspace/src/node_modules
が、これではうまく行かず、npm install
をした際にホスト側のディレクトリにずらーっとライブラリ群が同期されてしまいました。
前回node_modules
を同様の方法で外したつもりだったのですが、どうも 1 つ上の階層のものしかうまくいかないようで、もう一行足す必要がありました。
services:
node:
build: ./node
volumes:
- ../:/workspace:cached
- ../src:/workspace/src
- /workspace/src/node_modules
このようにすることで、やっとホストのディレクトリとの同期が外れ、node_modules
は Docker の Volume としてマウントされました。
Docker 側からnpm install
しても、ホスト側のnode_modules
にはライブラリ群が入ってこず、同期されるファイルの容量を少なくすることができます。
Laravel ではnode_modules
の他に、vendor
も同様に書くことで上記のレスポンス速度が 10 倍から 15 倍に改善されるようになりました。
軽量のライブラリなら問題ないですが、フルスタックフレームワークとなるとファイルサイズが大きくなるので、それをずっとマウントした状態でいると遅くなるのも当然のことでした。
Docker 上で開発する上ではライブラリ群は必ず Docker Volume に指定し、ホストと同期した状態にしないということが必要です。