お疲れ様です。tkmiです。
React で開発用の Docker コンテナを作っていると、
コンテナを立ち上げるたびに npm install が毎回走ってしまうこと、ありませんか?
最初は気にならなくても、ちょっとした修正や再ビルドのたびに毎回数分待つのは地味にストレスですよね。
実はこの問題、Docker のキャッシュをうまく使うだけで一発解決できます。
この記事では、
「React のコンテナで npm install を毎回やらなくて済むようにする」方法を紹介します。
よくあるDockerfile
まずはよく見かける書き方。
WORKDIR /app
COPY . .
RUN npm install
CMD ["npm", "run", "dev"]
この構成だと、COPY . . でプロジェクト全体をコピーしているため、
たとえ小さなファイル(たとえば README.md)を変えただけでも
Docker は「中身が変わった」と判断して npm install を再実行してしまいます。
改善した Dockerfile(キャッシュを効かせる)
では、キャッシュを効かせる正しい順番に直してみましょう。
FROM node:20
WORKDIR /app
# まず依存関係ファイルだけコピー
COPY package*.json ./
# npm install(ここでキャッシュされる)
RUN npm ci
# 残りのソースをコピー
COPY . .
CMD ["npm", "run", "dev"]
ポイントは以下
| 処理順序 | 意味 |
|---|---|
COPY package*.json ./ |
依存関係のファイルだけコピー |
RUN npm ci |
npm install をここで実行(キャッシュ対象) |
COPY . . |
ソースコードを最後にコピー(依存は変わらない限り再installしない) |
npm ci は npm install より速く、再現性が高いのでおすすめです。
CI/CDでもよく使われるコマンドですね。
docker-compose.yml の設定例
次に、docker-compose を使う場合の設定例です。
services: frontend:
build: .
ports:
- "5173:5173"
volumes:
- .:/app
- /app/node_modules # ホスト側にマウントしない
command: npm run dev
ここも地味に重要ポイントです。
-
volumesで/app/node_modulesをコンテナ側に確保することで、
ホストの node_modules を上書きしない ようにしています。 -
ホスト側の
node_modulesをマウントしてしまうと、環境差分で壊れることがあります。
効果
この設定にしておくと…
-
コンテナを再ビルドしても
npm installはスキップされる -
起動が一瞬で終わる(ほんとに体感で速くなる)
-
依存関係を変えたときだけ
docker compose build --no-cacheで再install
ちょっとした工夫ですが、開発体験がかなり快適になります。
まとめ
| 問題 | 解決方法 |
|---|---|
| npm install が毎回走る | package.json だけ先にCOPYしてキャッシュを効かせる |
| node_modules が壊れる | /app/node_modules をコンテナ側に保持する |
| install が遅い | npm ci を使う |
これだけで、React の Docker 開発がかなり快適になります。
「npm install 遅いな〜」と思ったら、まずこのキャッシュ戦略を試してみてください。

