node_modules
の取り扱いには注意が必要
Dockerを利用して環境構築をする際にはnode_modules
の取り扱いに注意する必要があります。
何も意識していないとホスト側でyarn install
などをしてしまうとエラーが発生することがあります。
またyarn install
などをDockerfile
で実行した際にnode_modules
が削除されたりします。
以下の記事ではコンテナ内のnode_modulesが消える問題の改善方法について記載しています。
しかし、上記の記事に記載している方法ではホスト側のnode_modules
が空になってしまいます。
今回は、ホスト側のnode_modules
が空になる問題の改善方法について記載します。
Next.js
の環境で試したのでNext.js
で記載しますが他でも応用可能と思います。
ホスト側のnode_modules
が空になる原因と改善方法
原因
docker-compose.yml
を以下のようにすることでnode_modules
に対してボリュームを設定してバインドマウントから除外しています。
バインドマウントから除外することでコンテナ内のnode_modules
が消えることは回避できますが、 node_modules
がボリュームで管理されるようになるため、ホスト側には反映されなくなります。
そのため、ボリュームで管理されているnode_modules
のみ空となってしまいます。
version: '3.9'
services:
front:
build: .
volumes:
- .:/myapp
- node_modules:/myapp/node_modules
environment:
NODE_ENV: development
ports:
- 3000:3000
volumes:
node_modules:
バインドマウントやボリュームの違いなどについては以下の記事をご参照ください。
改善方法
以下で紹介する方法はWindowsでは動作しないようです。
docker-compose.yml
を以下のようにすることでボリュームで管理されているnode_modules
の内容をホスト側にも表示できます。
version: '3.9'
services:
front:
build: .
volumes:
- .:/myapp
- node_modules:/myapp/node_modules
environment:
NODE_ENV: development
ports:
- 3000:3000
volumes:
node_modules:
driver: local
driver_opts:
type: none
device: ${PWD}/node_modules
o: bind
下のvolumes
内のdevice
には絶対パスを記述する必要があります。
これで、docker compose up
するとホスト側にもnode_modules
の中身が表示されます。
$ docker compose up
[+] Running 3/3
⠿ Network next_default C... 0.0s
⠿ Volume "next_node_modules" Created 0.0s
⠿ Container next-front-1 Created 93.0s
Attaching to next-front-1
next-front-1 | yarn run v1.22.18
next-front-1 | $ next dev
next-front-1 | ready - started server on 0.0.0.0:3000, url: http://localhost:3000
next-front-1 | wait - compiling...
next-front-1 | event - compiled client and server successfully in 2.2s (124 modules)
上のContainer next-front-1 Created 93.0s
を見てわかるとおり、ボリュームが作成された後、初回のdocker compose up
に時間がかかります。
また注意点としては、ホスト側に空のnode_modules
を用意する必要があります。
用意していないと以下のようなエラーが出ます。
Error response from daemon: error while mounting volume
'/var/lib/docker/volumes/next_node_modules/_data': failed to mount local volume:
mount /Users/user_name/Documents/sources/docker-next-test/Next/node_modules:
/var/lib/docker/volumes/next_node_modules/_data, flags: 0x1000:
no such file or directory
空の node_modules を用意してもエラーが出る場合
空のnode_modules
を用意してdocker compose build
したにもかかわらず以下のようなエラーが出ることがあります。
$ docker compose build
$ docker compose up
[+] Running 3/0
⠿ Network next_default C... 0.0s
⠿ Volume "next_node_modules" Created 0.0s
⠿ Container next-front-1 Created 0.0s
Attaching to next-front-1
next-front-1 | yarn run v1.22.18
next-front-1 | $ next dev
next-front-1 | /bin/sh: 1: next: not found
next-front-1 | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
next-front-1 | error Command failed with exit code 127.
コンテナ内で以下のコマンドを実行し、node_modules
が本当に空か確認します。
myuser@36f641e85791:/myapp$ ls -a node_modules
. .. .DS_Store
ホスト側のnode_modules
に.DS_Store
があれば、これがコンテナ側に反映されてしまうことが原因です。
ホスト側のnode_modules
内の.DS_Store
を削除するために以下を実行します。
$ rm node_modules/.DS_Store
そしてdocker compose down -v
→ docker compose up
で改善します。
なお上記の他にホスト側でもyarn install
することや(ホスト側が空になる状態であればホスト側の変更はコンテナ内に反映されません)、VSCodeで Remote - Containers
を利用することでも対処できます。
Remote - Containers
の使用方法については以下をご参照ください。
またホスト側にnode_modules
の中身が表示されるようになりましたが、ホスト側の変更がコンテナ内に反映されてしまいます。
ホスト側でyarn install
などをするとエラーの原因となることがあります。
ホスト側でのyarn install
等を禁止する方法については以下のページをご参照ください。