Skip to main content

第15章:node_modules問題(どこに置く?)📦😮

この章は「DockerでNode/TS開発するとき、node_modules をどこに置けば詰まらないか?」を“完全に腹落ち”させる回だよ〜!😆✨ 結論からいくと、コードは共有(bind mount)node_modules はコンテナ側(volume) が最強です💪🔥


1) まず結論:おすすめ方針はこれ!🏁😎

✅ 一番おすすめ(迷ったらこれ)

「プロジェクト全体をマウント」しつつ、node_modules だけ“別の置き場(ボリューム)”にする作戦!📦➡️🧰

  • ホスト(Windows)で編集したコードは即反映📝⚡
  • node_modules はコンテナ(Linux)に合う形で維持🐧✅
  • 速度も安定しやすい🚀

この“node_modulesだけボリューム隔離”がよく使われるのは、**bind mountがコンテナ内の既存ファイルを“覆い隠す”**からなんだよね👻 (だから普通に .:/app とやると、イメージ内に入ってた node_modules が見えなくなる)(Docker Documentation)


2) なんで node_modules が問題になるの?地雷3つ💣💣💣

地雷①:マウントで node_modules が“消えたように見える”😵

bind mount(.:/app)は、コンテナ側の /app に元からあったものを隠しちゃうんだ。 つまり、イメージ作成時に npm ci して /app/node_modules を作っても、起動時のマウントで見えなくなることがあるよ😇(Docker Documentation)


地雷②:Windowsで作った node_modules をLinuxコンテナに持ち込むと壊れる🪟➡️🐧💥

ホスト(Windows)で npm i した node_modules には、**Windows用のネイティブ依存(バイナリ)**が混ざることがあるよね。 それをLinuxコンテナで使おうとすると、互換性がなくてエラーになりがち😱 (例:rollup-linux-x64-gnu が見つからない系など)(GitHub)


地雷③:node_modules をホスト共有すると重い&不安定🧱🐢

node_modules はファイル数が多いから、共有(ファイル同期)に乗せると遅くなりやすいよ💦 Docker公式も「キャッシュやDBなどの非コード系はボリューム(Linux側)に置くと良い」って方向を推してる👍(Docker Documentation)

さらにWindows+WSL2環境だと、**bind mountするなら“Linux側のファイルシステムにコードを置く”**のが定番の最適化だよ🚀 (Windows側パスより速い&安定しやすい)(Docker Documentation)


3) ハンズオン:わざと詰まって→直して覚える🧪😆

ここでは Todo API(Node/TS)を想定して、ありがちな事故→王道解決を体験するよ〜!🎮✨


Step A:まず“事故る構成”を作る(体験用)💥

ありがちcompose(これだと詰まりやすい)

services:
api:
build: .
working_dir: /app
volumes:
- .:/app
command: npm run dev
ports:
- "3000:3000"

これで Dockerfile内で npm ci してても、起動時に .:/app マウントで /app/node_modules が隠れて、 Cannot find module 系のエラーが出たりする😇(Docker Documentation)


Step B:解決①(最短・強い):node_modules を“匿名ボリューム”に逃がす🏃‍♂️💨

✅ これが超定番の「node_modules隔離」構成

services:
api:
build: .
working_dir: /app
volumes:
- .:/app
- /app/node_modules
command: npm run dev
ports:
- "3000:3000"

ポイントはこの1行👇

  • - /app/node_modulesホストの node_modules を持ち込ませず、コンテナ側に専用置き場を作る

これで「コードは共有するけど、node_modules はコンテナに居てね〜」が成立するよ😎


Step C:解決②(管理しやすい):node_modules を“名前付きボリューム”にする🏷️🧰

匿名でもOKだけど、意図が見える掃除しやすいのが名前付きボリューム✨

services:
api:
build: .
working_dir: /app
volumes:
- .:/app
- node_modules:/app/node_modules
command: npm run dev
ports:
- "3000:3000"

volumes:
node_modules:

Dockerのボリュームは「高速I/O向き」で、用途的にも相性が良いよ👍(Docker Documentation)


Step D:依存を“コンテナ内で確実に入れる”✅📦

node_modules を隔離したら、依存は コンテナ内で入れるのが一番安全!

例:

  • まず依存だけ入れる(1回目)

    • docker compose run --rm api npm ci
  • その後に起動

    • docker compose up

「Linuxコンテナ用の依存」が入るから、Windowsバイナリ混入事故も避けられるよ🛡️(GitHub)


4) “WSL2でどこに置く?”も超重要🪟🐧📌

✅ 体感が変わるコツ

プロジェクトはできれば WSL2側のファイルシステム(Linux側)に置くと快適になりやすい💨 Docker公式も「bind mountするならLinux側に置くのがおすすめ」って言ってるよ📣(Docker Documentation) VS Code側も同じ方向で、WSL上に置くとパフォーマンス改善しやすいよ〜って話がある👍(Visual Studio Code)


5) 2026っぽい“さらに楽する”選択肢🆕✨

選択肢①:Compose Watchで「同期対象を賢くする」👀🔁

最近は Compose の watch で、node_modules/ を無視するみたいな運用もしやすいよ〜! 「bind mountの代わり」ではないけど、開発向けに粒度高く扱えるのが強み💪(Docker Documentation)


選択肢②:Docker Desktopの“高速共有”機能(大規模向け)🚀

Docker Desktopには、共有を速くする仕組み(同期キャッシュ系)も用意されてるよ。大きいプロジェクトで効きやすい👍(Docker Documentation) (※環境によって使える/設定できる範囲が違うから、困ったらここを疑うと吉!)


6) よくある症状→即診断チートシート🩺📋✨

  • Cannot find module ....:/appnode_modules が隠れてる可能性大! → - /app/node_modules(または名前付きvolume)を追加!(Docker Documentation)

  • ...-linux-x64-gnu が無い / ELF 系 / バイナリ不一致っぽい → Windowsで入れた node_modules をLinuxが読もうとして事故ってるかも! → コンテナ内で npm ci しよう🛡️(GitHub)

  • とにかく遅い(特に install が地獄)🐢node_modules をホスト共有してない? → ボリュームに逃がそう!&コードはWSL側に置くと改善しやすい🚀(Docker Documentation)


7) AI活用(この章はAIと相性よすぎ🤖✨)

そのままコピペでOKなプロンプト例いくよ〜!😆

  • 💬「このcompose構成で、node_modules をLinuxコンテナ側に保持しつつ、ホットリロードも効く最小構成にして。Windows+WSL2前提でありがちな罠も添えて」
  • 💬「このエラー(貼る)って、Windowsの node_modules をコンテナにマウントしてるせい?可能性順に原因トップ3と直し方をください」
  • 💬「pnpm/yarn/npmのどれでもいいから、node_modules の置き場所を事故らない方針にしたい。今の構成(貼る)に合わせた提案して」

8) まとめ:この章の合格ライン🏆🎉

✅ 次の3つを説明できたら勝ち!

  1. bind mount は既存ファイルを隠す(だから node_modules が消える)(Docker Documentation)
  2. Windowsの node_modules をLinuxコンテナに持ち込むと壊れうる(GitHub)
  3. 解決は 「コードは共有」「node_modules はボリューム」 が基本形💪(Docker Documentation)

次の章(第16章:ボリュームの基本運用🧰)で、この node_modules ボリュームも含めて「作る・見る・消す」が気持ちよくできるようにしよう😆✨