はじめに
Docker上でyarn add
とかyarn update
を走らせると
主に、Linking dependencies...
のところにものすごく時間がかかっていて
調べてみたところ、私の環境固有ではないようで
幾つか対策を試み実際に効果を調べた
結論
- セキュリティソフトのリアルタイム監視が影響している可能性あり(win & mac)
- mac環境ではosxfsというファイル共有システム?のパフォーマンスにより遅延が生じる(mac)
- mac環境での対策として、以下の方法が有効でした
- volumesの
:cached
optionを使用する(同期の遅延を許容する) - 読み書きが頻繁に行われるディレクトリに対しては、anonymous volumeや、named volumeとして指定することでhost側と同期しないようにする(そもそもhost側と同期しないようにする)
- 頻繁に読み書きするディレクトリを知っている、調べる(ここが重要な気がします、幾つか例を残していますので参考になれば)
追記(2020.10.1)
docker-compose.yml
で./node_modules
をnamed volumeとして設定している部分のpathに誤りがありこれを訂正すると、体感でわかるほど高速化されました
当初よりだいぶvolumeの仕組みを理解してdocker-compose.yml
を書けるようになりました
Dockerのversionも変えてしまったので再計測は行なえませんが(今思うともともとの計測手順にも問題あり)、読み書きが頻繁に行われるディレクトリはhost側と同期しないようにする、が重要な気がします
ということで計測結果はそこそこに(笑)
セキュリティソフトの設定変更はリスクもありそうなので、参考程度に留めていただき、読み書き頻回なディレクトリのパスを調べる、可能であればそのパスをhostマウントから除外する、難しいようであれば:cached
オプションを試みるがいいように思います
# 誤)
- node_modules:/mysrc/node_modules:cached
# 正)
- node_modules:/myapp/node_modules:cached
以下修正済みです
環境・計測方法
環境
- Mac OS Mojave 10.14.6
- Docker on mac 2.3.0.4
- Rails 6.03
- Ruby 2.7.1
$ docker-compose run app yarn --version
1.22.4
計測条件
- Avast (on or off) = セキュリティソフトのリアルタイム監視をon or off
- cached(あり or なし) = volumesの
:cached
オプションの有無 - volume mount (host or named) = hostのディレクトリをマウントする(=host、default), named volumeでhost mountから除外(=named)
上記環境にて以下のコマンドに要する時間を計測しました
docker-compose exec app yarn upgrade
結果
セキュリティソフトの設定変更
# Avast: on + cached: なし + volume: host (Default)
Done in 420.56s.
# Avast: off + cached: なし + volume: host
Done in 290.60s.
さらにnamed volumeを使用する
# Avast: off + cached: なし + volume: named
Done in 219.31s.
さらにcachedオプションを追加
# Avast: off + cached: あり + volume: named
Done in 204.73s.
まだ遅いけど、半分以下に短縮できました
一番影響したのはセキュリティソフトの設定かな
Appendix
Dockerのvolume3種類
以下にまとめました
目的から考えるDockerのvolume3種 - Qiita
上記を反映させたdocker-compose.yml
version: '3'
services:
app:
build: .
command: ash -c "rm -f tmp/pids/server.pid && ./bin/rails s -p 3000 -b '0.0.0.0'"
volumes: # 重要
- .:/myapp:cached
- rails_cache:/myapp/tmp/cache:cached # named volume化 + cached option
- node_modules:/myapp/node_modules:cached # named volume化 + cached option
- yarn_cache:/usr/local/share/.cache/yarn/v6:cached # named volume化 + cached option
- bundle:/bundle:cached # named volume化 + cached option
tmpfs:
- /tmp
tty: true
stdin_open: true
ports:
- "3000:3000"
environment:
DATABASE_HOST: db
DATABASE_PORT: 5432
DATABASE_USER: postgres
DATABASE_PASSWORD: password
WEBPACKER_DEV_SERVER_HOST: webpacker
depends_on:
- db
- webpacker
-
webpacker:
build: .
command: ./bin/webpack-dev-server
volumes:
- .:/myapp:cached # これだけではダメで
- node_modules:/myapp/node_modules:cached # こうしないと他のコンテナとnode_modulesが共有されない
environment:
RAILS_ENV: development
NODE_ENV: development
WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
tty: false
stdin_open: false
ports:
- '3035:3035'
db:
image: postgres:11.0-alpine
volumes:
- postgres:/var/lib/postgresql/data:cached
environment:
- TZ=Asia/Tokyo
ports:
- '5432:5432'
environment:
PGDATA: /var/lib/postgresql/data/pgdata
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_INITDB_ARGS: '--encoding=UTF-8 --locale=ja_JP.UTF-8'
TZ: Asia/Tokyo
volumes: # named volumeを使用する場合は記述必須
rails_cache:
node_modules:
yarn_cache:
postgres:
bundle:
yarnのキャシュディレクトリを調べる方法
docker-compose run app yarn cache dir
参考
当初windowns環境のセキュリティソフトが影響しているとのことでしたが、mac環境でも同様の現象が起きることが報告されています
Linking dependencies is taking a long time · Issue #1496 · yarnpkg/yarn
セキュリティソフトの関与について気づきをいただけました
Yarn ver1.9.2で「Linking dependencies...」で時間がかかる方へ - Qiita
キャシュディレクトリを調べかた
dockerでyarn addすると遅い問題を改善する - Qiita