node_modules
の取り扱いには注意が必要
Dockerを利用して環境構築をする際にはnode_modules
の取り扱いに注意する必要があります。
何も意識していないとホスト側でyarn install
などをしてしまうとエラーが発生することがあります。
またyarn install
などをDockerfile
で実行した際にnode_modules
が削除されたりします。
以下の記事ではコンテナ内のnode_modulesが消える問題の改善方法について記載しています。
しかし、上記の記事に記載している方法ではホスト側のnode_modules
が空になってしまいます。
その改善方法については以下の記事にまとめました。
記事のように設定するとホスト側にnode_modules
の中身を表示できますが、ホスト側の変更がコンテナ内に反映されてしまいます。
ホスト側でyarn install
などをするとエラーの原因となるため、今回はホスト側のnode_modules
が空になる問題の改善方法について記載します。
Next.js
の環境で試したのでNext.js
で記載しますが他でも応用可能と思います。
ホスト側でyarn install
などを不可にする
ホスト側でyarn install
やyarn add
をするとエラーが出るようにすることで対応します。
まず、.yarnrc
を作成します。
そして以下のように記述します。
--modules-folder /myapp/node_modules
yarnを使用した際に--modules-folder /myapp/node_modules
がつくようになります。
--modules-folder
については以下をご参照ください。
次にDockerfileを以下のようにします。
FROM node:16.14.2
ENV USER_NAME=myuser
ENV TZ=Asia/Tokyo
# PATH 追記
ENV PATH="/myapp/node_modules/.bin:$PATH"
WORKDIR /myapp
# .yarnrc 追記
COPY package.json yarn.lock .yarnrc ./
RUN yarn install --frozen-lockfile
RUN adduser ${USER_NAME} && \
chown -R ${USER_NAME} /myapp
USER ${USER_NAME}
EXPOSE 3000
CMD ["yarn", "dev"]
これで、yarn install
をホスト側で実行すると以下のようなエラーが出てyarn install
できなくなります。
$ yarn install
yarn install v1.22.17
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
error An unexpected error occurred: "EROFS: read-only file system, mkdir '/myapp'".
info If you think this is a bug, please open a bug report with the information provided
in "/Users/user_name/Documents/sources/docker-next-test/Next/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
yarn add
も同様です。
$ yarn add <package>
yarn add v1.22.17
[1/5] 🔍 Validating package.json...
[2/5] 🔍 Resolving packages...
[3/5] 🚚 Fetching packages...
[4/5] 🔗 Linking dependencies...
error An unexpected error occurred: "EROFS: read-only file system, mkdir '/myapp'".
info If you think this is a bug, please open a bug report with the information provided
in "/Users/user_name/Documents/sources/docker-next-test/Next/yarn-error.log".
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
また、これはホスト側でyarn install
などを不可にする他にも、以下のような事象を改善します。
node_modules
にボリュームを設定した状態で、以下を実行するとコンテナ側のnode_modules
が空になります。
$ docker compose run --rm front yarn create next-app --ts myapp_name && \
cd $_ && mv * .* .. && rmdir ${PWD} && cd ../
ホスト側でプロジェクトのルートディレクトリに展開するためこのように実行しています。
しかしこれでは、コンテナ内の/myapp/node_modules
に変更が反映されません。
コンテナ内のnode_modules
は空のままであるため、docker compose up
するとエラーが出ます。
$ docker compose up
[+] Running 1/0
⠿ Container next-front-1 Created 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 | info Visit https://yarnpkg.com/en/docs/cli/run for documentation about
this command.
next-front-1 | error Command failed with exit code 127.
next-front-1 exited with code 127
.yarnrc
を前述のとおり作成すると/myapp/node_modules
にインストールされるようになるため、この問題も改善されます。
これでyarn install
などはできなくなりましたが、まだnpm install
はできてしまいます。
node_modules
が存在しない状態でホスト側でnpm install
したり、ホスト側でnpm ci
を実行してしまうとエラーの原因となることがあります。
詳細は以下をご参照ください。
また、yarnを使用しているのにnpm install
してしまうとyarn.lock
の他にpackage-lock.json
も作成されてしまいます。
そのため、次はnpm install
もできないようにします。
npm install
をできないようにする方法は以下をご参照ください。
yarn V3の場合
yarn V3の場合には.yarnrc
ではなく、.yarnrc.yml
を使用する必要があります。
.yarnrc.yml
に以下のように記述することで同じことができます。
yarnPath: .yarn/releases/yarn-3.2.0.cjs
cacheFolder: "/myapp/.yarn/cache"
yarn V3はnode-modules
ではなくcache
フォルダ経由で依存関係を解決しています。
そのため、cache
フォルダのパスを指定することでホスト側でyarn add
をするとエラーが出るようにできます。
$ yarn add <package>
Internal Error: ENOENT: no such file or directory, mkdir '/myapp'
Error: ENOENT: no such file or directory, mkdir '/myapp'
yarn install
でも同様です。
$ yarn install
Internal Error: ENOENT: no such file or directory, mkdir '/myapp'
Error: ENOENT: no such file or directory, mkdir '/myapp'