Dockerでnode.jsの開発環境でnode_moudlesが見えなくて困ってどうしたか
docker及びdocker-composeでnodejsの開発環境を構築しました。
最初はdockerfileでyarn installする構成で考えてました。
dockerfile及びcomposeはこんな感じ。
FROM node:10.14.2-alpine WORKDIR /app COPY package.json ./ COPY yarn.lock ./ RUN yarn install COPY . /app
version: '3'
services:
node:
build: .
volumes:
- .:/app/
- /app/node_modules
ports:
- "3000:3000"
dockerファイルでローカル側のpackage.jsonとyarn.lockをコンテナ側にコピーしてyarn installを実行
docker-composeでボリューム先をカレントディレクトリとnode_modulesを指定する。
ここでボリューム先にnode_modulesを指定していないと、マウント時にコンテナ内のnode_modulesフォルダが隠れて見えなくなる。
参照 - Lessons from Building a Node App in Docker Volume Trickの項目
これで問題なく、動くのだがローカル側からnode_modulesフォルダを見ると中身が見えず空っぽになってしまう。

この状態だとコーディング時にvscode等のエディタ上でlintや参照エラーが大量に表示されて困るし、typescirptを使ってると補完も効かず散々な状態になる。
じゃあ、どうするか?
対応方法1
仕方ないのでlocal側でもnode環境を入れて,、yarn installする。
ただ、ローカル環境が汚染されてDocker入れた意味ないじゃんという感じになる。
敗北感がものすごい
対応方法2
マウント後のボリュームの変更はローカル側にも同期される。
この仕組みを利用してdockerfileでyarn installはせずに, docker-composeのcommandでyarn installするようにした。
起動時に毎回、yarn installが呼ばれてしまうが、2度目以降は差分の確認だけなので1秒ぐらいで終わる。
package.jsonが変更されても、docker-compse buildをしなくてもパッケージが更新されるのでこれで良しとした。
dockerfileとdocker-compose.yamlは以下のように変わります。
FROM node:10.14.2-alpine WORKDIR /app
version: '3'
services:
node:
build: .
volumes:
- .:/app/
- /app/node_modules
ports:
- "3000:3000"
command: yarn install # <- これを追加
これでnode_modulesの中身も見える!やったー!
ただ、、、。
docker-compose側でyarn installしなきゃ駄目で、dockerのimageとしては環境が揃わないというのが、スマートじゃないなー感じてしまう。
悩ましい。。。