【JavaScript】Docker上でのnpm/yarnの操作を10倍早くする方法

【JavaScript】Docker上でのnpm/yarnの操作を10倍早くする方法


# docker # node # npm # yarn

Dockerでnpm install とか yarn install をすると何か遅いなあと感じたことはないでしょうか?

私はDocker環境上でしかnpmやyarnを使っていなかったので中々気が付かなかったのですが、 先日友人のエンジニアにお前のdocker-comoseいけてないから変えたほうがいいよ、と教えてもらいました。

誇張抜きに10分かかっていた初期のモジュールのインストールが1分未満で終わるようになるなど、10倍以上早くなりました。

以下で何が悪かったのか、何を変えれば高速化に繋がるのか解説していきたいと思います。

modulesの追加等が遅かった原因

まず、私のdocker-composeはこんな感じになっていました。

version: '3'

services:
  lonet:
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - ..:/workspaces/
    ports:
      - "3000"
    command: sleep infinity

なんてことはない、普通のdocker-composeです。

指定したディレクトリ配下のソースを全てコンテナにマウントして開発を行っていました。 正常に動いていますし、特に問題は感じていませんでした。

以下は、docker上の/workspaces/node_modules というような配置を想定しています。 以下のような状態です。

  • コンテナ側のパス… /workspaces/node_modules
  • ホスト側のパス…. ./node_modules

が、このnode_modulesが他のファイルと同様にマウントされるように設定していた事が問題でした。 (bind mountsと言うようです。)

細かいことは分からなのです、Docker上とホストの同期が行われるためかなり動作が低速になるとのことです。

ということで、原因はわかったので解決していきましょう。

node_modules用のVolumeを作ることで高速化

あれこれ解説するよりも見てもらった方が早いと思うので、結論を記載します。

version: '3'

services:
  lonet:
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - ..:/workspaces/
      - node_modules_volume:/workspaces/node_modules
    ports:
      - "3000"
    command: sleep infinity

volumes:
  node_modules_volume:

はい、完成です。

赤字の部分が先程から変わった部分です。

node_modules用のボリュームを定義して上げて、そのボリュームをマウントします。

このようにすることで、「/workspaces/node_modules」通常のファイルシステムのマウント(bind mounts)ではなく、動作が高速なボリューム(この場合はnode_modules_volume)が使われるようになります。

npm等に限らず、頻繁に読み書きが行われるようなディレクトリに関してはvolumeを適切に使うようにするほうが動作速度の観点からベターなようです。

ここらへんはなかなか難しいですが、効率的に進めるために色々知識を蓄えていきたいのものです。

それではお疲れさまでした!