どうも。諸々の事情で関西の某地域のバス[お察しください]になった者です。
問題
Dockerは最早聞き慣れた言葉になっていると思います。そして、NodeJSやこれを使うフロントエンドと連携する時、こんなコードを書くと思います。
version: "3"
services:
db:
image: mongo:latest
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: prj
MONGO_INITDB_ROOT_PASSWORD: prj
ports:
- 27017:27017
volumes:
- ./data/db:/data/db
backend:
build: ./backend
stop_signal: SIGINT
ports:
- 8080:8080
volumes:
- .:/opt/code
depends_on:
- db
environment:
DEVEL: 'true'
CONFIG_NAME: devel.conf
frontend: # ここにNodeJSが使われている
build: ./frontend
stop_signal: SIGINT
ports:
- 4200:4200
volumes:
- ./frontend:/code
depends_on:
- backend
で、実行するとコンテナが色々準備してくれる・・・と。ですが、これだと、ホスト側のnode_modules
ディレクトリとコンテナ側のnode_modules
が共有される事になります。オマケに、環境にもよりますが、少なくともLinux上でコードを書いているオタクな人の環境だと、package.json
やpackage-lock.json
の所有権が別の誰かになってしまう事もあります。これだとどうもやりにくい。なので、せめてnode_modules
だけはホスト側とコンテナ側で別々にしておきたい。
そんな方法あるの? はいありました。
/code/node_modules
にVolumeを割り当てる
Dockerのボリュームというのは、外部のストレージ、つまりホスト側のどこかしらのディレクトリからマウントしたり、コンテナとは別のストレージにデータを保存したい場合なんかに用いられていますが、実は、VolumeによってマウントされたディレクトリのサブディレクトリにVolumeをマウントしても良いんです。つまり、さっきのdocker-compose.yml
を次のように書き換えます。
version: "3"
services:
db:
image: mongo:latest
restart: unless-stopped
environment:
MONGO_INITDB_ROOT_USERNAME: prj
MONGO_INITDB_ROOT_PASSWORD: prj
ports:
- 27017:27017
volumes:
- ./data/db:/data/db
backend:
build: ./backend
stop_signal: SIGINT
ports:
- 8080:8080
volumes:
- .:/opt/code
depends_on:
- db
environment:
DEVEL: 'true'
CONFIG_NAME: devel.conf
frontend:
build: ./frontend
stop_signal: SIGINT
ports:
- 4200:4200
volumes:
- ./frontend:/code
- /code/node_modules # ここに注目!!
depends_on:
- backend
こうすることによって、node_modules
を削除する時にroot権限を使う必要がなくなり、ホスト側でNodeJSのコマンド、ng update
なんかを実行することができます❤
めでたしめでたし
参考記事
- Stack Overflow - Add a volume to Docker, but exclude a sub-folder