🐳

docker composeでのnode_modules問題を解決する

2024/09/08に公開

これは何?

docker composeを利用した開発環境を用意するにあたりnode_modulesの扱いが結構面倒なので、コピペして使いまわせるようにしておきたい。

やりたいことはコンテナ上で管理してるnode_modulesをホストにも持ってきたい(dev containerの設定、都度docker cpしたくないという怠惰)。

詳細の解説は参考にさせていただいた記事や公式ドキュメントに任せたい。

諸々の構成ファイル

記事を簡単にするために以下のようなディレクトリ構成を題材(Next.jsを使ったプロジェクトのつもり)にする。

.
├── compose.yaml
├── app.Dockerfile.dockerignore
├── app.local.Dockerfile.dockerignore
├── docker
│   └── app
│       ├── app.Dockerfile.      # 検証・本番環境用
│       └── app.local.Dockerfile # 開発環境用
└── app 
    ├── package-lock.json
    ├── package.json
    └── ... アプリケーションコード諸々
compose.yaml
services:
  app:
    container_name: app
    build:
      context: .
      dockerfile: ./docker/app/app.local.Dockerfile
    ports:
      - "3000:3000"
    volumes:
      - ./app:/usr/src/app:cached
      - node_modules:/usr/src/app/node_modules
    command: npm run dev
    environment:
      - WATCHPACK_POLLING=true

volumes:
  node_modules:
    driver: local
    driver_opts:
      type: none
      device: ${PWD}/app/node_modules
      o: bind
app.local.Dockerfile
# syntax=docker/dockerfile:1
FROM node:22.8.0-alpine3.20

WORKDIR /usr/src/app

RUN apk update && \
    apk add --no-cache wget git unzip vim curl python make g++

COPY ./app/package*.json .

RUN npm i

ENV NODE_ENV=development

ポイント

  1. node_modulesを名前付きvolumeに指定
  app:
    volumes:
      - ./app:/usr/src/app:cached
      - node_modules:/usr/src/app/node_modules
  1. 名前付きvolumeをホストにマウントする設定
volumes:
  node_modules:
    driver_opts:
      type: none
      device: ${PWD}/app/node_modules
      o: bind

※driverはデフォルトでlocalなので特に指定しなくても良いかもだが、動作に問題がある際は指定するのが無難

参考にさせていただいた資料

https://qiita.com/P-man_Brown/items/c2a69d943853cb381fbe
https://qiita.com/P-man_Brown/items/5a82ad98cb96206343b9
https://qiita.com/keitean/items/23c75f834cc839ca9634
https://stackoverflow.com/questions/35841241/docker-compose-named-mounted-volume
https://github.com/compose-spec/compose-spec/blob/main/spec.md#volumes-top-level-element
https://docs.docker.com/reference/cli/docker/volume/create/#opt

Docker周りのおまけ資料

コンテナ化が当たり前になってきているのでこのあたりは押さえておきたい。今回は開発環境用のコンテナだったのでrootユーザーのままにしている(開発中にパッケージ更新周りとかで面倒になるのでサボった)が、権限まわりとかは特に気をつけないと。。。
https://future-architect.github.io/articles/20240726a/
https://docs.docker.com/build/building/best-practices/
https://zenn.dev/forcia_tech/articles/20210716_docker_best_practice
https://qiita.com/Tsuyozo/items/c706a04848c3fbbaf055#copy---chownを使用する
https://zenn.dev/kynefuk/scraps/26a3d45029c277
https://chroju.dev/blog/docker_practices_2022

Discussion