LoginSignup
16
10

More than 1 year has passed since last update.

【Docker】コンテナ内のnode_modulesが消える問題を改善する

Last updated at Posted at 2022-04-28

はじめに

本記事はプログラミング初学者が学習を進めていて疑問に思った点について調べた結果を備忘録も兼ねてまとめたものです。
そのため、記事の内容に誤りが含まれている可能性があります。ご容赦ください。
間違いを見つけた方は、お手数ですが、ご指摘いただけますと幸いです。

node_modulesの取り扱いには注意が必要

Dockerを利用して環境構築をする際にはnode_modulesの取り扱いに注意する必要があります。
ホスト側でyarn installなどをしてしまうと下の記事のようにエラーが発生することがあります。

またyarn installなどをDockerfileで実行した際にnode_modulesが削除されたりします。

今回は、コンテナ内のnode_modulesが削除される問題の改善方法について記載します。
Next.jsの環境で試したのでNext.jsで記載しますが他でも応用可能と思います。

コンテナ内のnode_modulesが消える

前述したとおり、yarn installなどをDockerfileで実行した際にnode_modulesが削除されてしまうことがあります。
これは、Dockerfiledocker-compose.ymlを以下のように記述している場合に起こります。

Dockerfile
FROM node:16.14.2

ENV USER_NAME=myuser
ENV TZ=Asia/Tokyo

WORKDIR /myapp

COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

RUN adduser ${USER_NAME} && \
  chown -R ${USER_NAME} /myapp
USER ${USER_NAME}

EXPOSE 3000
CMD ["yarn", "dev"]
docker-compose.yml
version: '3.9'
services:
  front:
    build: .
    volumes:
      - .:/myapp
    environment:
      NODE_ENV: development
    ports:
      - 3000:3000

docker compose upすると以下のようなエラーが出ます。

ターミナル
$ docker compose up
[+] Running 2/2
 ⠿ Network next_default    Creat...                        0.0s
 ⠿ Container next-front-1  Cre...                          0.1s
Attaching to next-front-1
next-front-1  | yarn run v1.22.18
next-front-1  | $ next dev
next-front-1  | /bin/sh: 1: next: not found
next-front-1  | error Command failed with exit code 127.
next-front-1  | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
next-front-1 exited with code 127

原因はdocker-compose.ymlvolumesにあります。
ここではvolumes.:/myappと記述し、バインドマウントを設定しています。
バインドマウントはマウント時にホスト側の情報がそのまま反映され、そのあとコンテナ内で変更があればホスト側に反映されます。
よって、ホスト側にnode_modulesが存在しない状態でdocker compose upするとホスト側の情報がそのまま反映されます。
するとコンテナ内のnode_modulesがなくなってしまいます。

確認のためにdocker-compose.ymlからvolumes削除します。

docker-compose.yml
version: '3.9'
services:
  front:
    build: .
    # volumesを削除
    environment:
      NODE_ENV: development
    ports:
      - 3000:3000

変更後にdocker compose downdocker compose builddocker compose run front ls -aするとnode_modulesがあることが確認できます。

ターミナル
$ docker compose run front ls -a
[+] Running 1/0
 ⠿ Network myapp_default  Created      0.0s
.  ..  node_modules  package.json  yarn.lock

これは、バインドマウントが設定されておらず、ホスト側の情報がコンテナ内に反映されないためです。

再度docker-compose.ymlvolumesを記述しdocker compose downdocker compose builddocker compose run front ls -aします。
するとホスト側の情報がそのまま反映されnode_modulesは存在しません。

ターミナル
$ docker compose run front ls -a
[+] Running 1/0
 ⠿ Network myapp-_default  Created                            0.0s
.                 .editorconfig        .gitignore       Dockerfile
..                .env                 .husky           docker-compose.yml
.DS_Store         package.json         yarn.lock        .git

バインドマウントを設定したことでホスト側の情報がそのまま反映されていることがわかります。

改善方法

改善するためには、バインドマウントに加えてnode_modulesに対してボリュームを設定します。
Dockerfiledocker-compose.ymlを以下のようにします。

Dockerfile
FROM node:16.14.2

ENV USER_NAME=myuser
ENV TZ=Asia/Tokyo

WORKDIR /myapp

COPY package.json yarn.lock ./
RUN yarn install --frozen-lockfile

RUN adduser ${USER_NAME} && \
  chown -R ${USER_NAME} /myapp
USER ${USER_NAME}

EXPOSE 3000
CMD ["yarn", "dev"]
docker-compose.yml
version: '3.9'
services:
  front:
    build: .
    # 以下追記
    volumes:
      - .:/myapp
      - node_modules:/myapp/node_modules
    environment:
      NODE_ENV: development
    ports:
      - 3000:3000
# 以下追記
volumes:
  node_modules:

上記のようにするとエラーは出なくなります。

バインドマウントとボリュームを同時に設定した際に、ボリュームの方が優先されます。
そのため、node_modulesに関してはdocker compose upした際にホスト側の影響を受けることがなくなります。
node_modulesが削除されないため、エラーが出ません。

なお名前つきボリュームを利用していますが、匿名ボリュームでも同様に機能します。
バインドマウントやボリュームの違いについては以下の記事をご参照ください。

ただし、この方法ではnode_modulesはバインドマウントから除かれるため、ホスト側のnode_modulesが空になってしまいます。

これはホスト側でもyarn installすることや(ホスト側が空になる状態であればホスト側の変更はコンテナ内に反映されません)、VSCodeで Remote - Containersを利用することでも対処できます。
Remote - Containersの使用方法については以下をご参照ください。

しかし、ホスト側でyarn installせずにnode_modulesの中身を表示させる方法があります。
こちらについては以下にまとめましたのでご参照ください。

16
10
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10