🐳

Dockerでnode_modulesをホストとコンテナで同期しないようにする

2022/05/31に公開

Node.jsの開発などでdockerを使う際に微妙に厄介になるのがnode_modules ディレクトリになります

例えば以下のような docker-compose.yaml を使うとします

version: "3.3"
services:

  front:
    image: node:16
    command: sh -c "npm install && npm run dev" 
    volumes:
      # . に package.json などがある想定
      - ./:/workspace

このとき カレントディレクトリをまるごとマウントしてしまうと node_modules もホストとコンテナで同期されてしまうことになります。

これだとホスト側に node_modules が作成されて、意図しない挙動を招きかねません。(うっかり node_modules をいじったりしてしまうとか)

また例えば自前で Dockerfile を用意し、Dockerfile 内部で npm install などを実行していた場合、イメージ内の node_modules を削除してしまうことになります。

これを避けるためには以下のように名前付きボリュームを用意してあげることで node_modules が名前付きボリュームに格納され、ホストマシンに同期されることがなくなります

version: "3.3"
services:

  front:
    image: node:16
    command: sh -c "npm install && npm run dev"
    volumes:
      # . に package.json などがある想定
      - ./:/workspace

      # node_modulesを名前付きボリュームに隠す
      - front_node_modules:/workspace/node_modules

volumes:
  front_node_modules:

このテクニックは以下の記事で紹介されており、Volume Trick と呼ばれたりするみたいです

Lessons from Building a Node App in Docker

記事内では匿名ボリュームにしていますが、名前付きボリュームにしておいた方が色々と好都合な気がしました。

またこのテクニックは node_modules だけでなく、ほかの言語での似たようなディレクトリに関しても使えそうです

Discussion