こんにちは。KIYONOエンジニアです。
本日はDockerに関する記事です。
開発環境にてpackage.jsonを更新してbuild時にnpm installしてもコンテナ内のnode_modulesが更新されない問題の解決方法を解説します。
またなぜ更新されないかも詳しく書いておりますので、同じような状況に陥ってる方はぜひご参考にしていただければと思います。
問題の事象
前提
frontend:
build:
context: ./frontend/
dockerfile: Dockerfile/local/dockerfile
command: sh -c "npm run dev:inspect"
volumes:
- ./frontend:/app
- node_modules:/app/node_modules
env_file:
- .env
ports:
- "3000:3000"
volumes:
node_modules:
問題が生じた際の前提として、上記のようなdocker-compose.ymlを使っており、またDockerfile内でnpm installを記述し、ビルド時にnode_modulesをインストールする構成となっておりました。
問題
開発環境にて新しいライブラリを追加する際に、package.jsonを更新してから以下コマンドを実行してnpm installしてもコンテナ内のnode_modulesが更新されないという事象が発生しておりました。
docker compose build
そのためコンテナを立ち上げる際にではなく、立ち上げた後にnpm installを実行するという暫定策をとっていました。毎回コンテナを立ち上げた後にnpm installするのはとても面倒なので、コンテナ立ち上げ時にnode_modulesを更新するように検討したというのが対策の経緯になります。
原因
以下コマンドを実行した際に、Dockerfile内に記述されているnpm install(上図の①)が実行されます。その後、③のDockerホスト内あるnode_modulesでマウントすることで、コンテナ内のnode_modulesが反映される形となります。
docker-compose up --build
問題として、以下コマンドを実行して①でnpm installしても、Dockerホストのnode_modulesは更新されないため、最終的に③の処理にて更新前のnode_modulesで上書きされてしまい結果として、package.jsonの中身が更新されない状況が発生します。
解決方法
- Dockerホストのボリュームごと消してから、再度コンテナを作り直し、起動する(docker compose down -v → docker-compose up –buildの流れ)
- コンテナの立ち上げと同時にnpm installを実行する(コンテナ立ち上げた際にボリュームを更新する)⭐︎こちらを採用
1でも問題ないと思いますが、毎回docker compose down -vを実行してからコンテナを立ち上げるのが面倒で処理に時間がかかってしまうので、2の方を採用しました。
具体の処理としては添付のとおりです。
上図の通り、docker-compose.yml内のcommand内にnpm installを記述することによって、③のボリュームマウントの後にコンテナ内でnpm installを実行することで、アップデートされたnode_modulesがDockerホスト側のボリュームにも反映されます。これによりDokcerコンテナの起動時に最新のpackage.jsonの内容が反映されます。
補足:バインドマウントのみの挙動は?
バインドマウントのみだと上記のような挙動をとります。
ホスト側にnode_modulesを管理してない場合に、バインドマウント時にコンテ内のnode_modulesが削除されます。
ホスト側にnode_modulesを管理すれば?と思われるかもしれないが、ホスト側で管理するとPCのOSの制約を受けたり、またgithub等で管理するにもサイズがかなり大きくなってしまうのでホスト側でnode_modulesを管理するのは非推奨です。
まとめ
いかがだったでしょうか。開発環境の改善って後回しにしてしまいがちで、また取り掛かるにも内部で何をしてるかよくわからないということで改善が難しいかと思います。
同じようなお悩みを持っている参考になれば幸いです。
本日は以上です。
コメント