DockerでNext.jsの開発環境を作ったがローカルで開発することにした
Jul 24, 2022 21:40 · 2047 words · 5 minute read
Next.jsを使ったWebアプリ開発環境をDockerで作ってみました。
試行錯誤してみましたがパフォーマンスに難があり、最終的にはDockerは諦めてローカルで開発することにしました。
将来問題が解消されたときに続きから検証できるように、試したことをブログに残しておこうと思います。
目次
最初に結論
- DockerでNext.jsの開発環境を作ってみたが、動作が遅かった。
- 特に「繰り返し使うホットリロードが遅いこと」が辛かったので、結局ローカルで開発することにした。
Docker+Next.jsの開発環境
今回用意した環境はこちら。 後述する参照URLを参照させていただきました。
$ cat Dockerfile
FROM node:16.16
WORKDIR /usr/src/app
USER node
% cat docker-compose.yml
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./:/usr/src/app
environment:
- WATCHPACK_POLLING=true
command: sh -c "cd sample-app && npm run dev"
ports:
- "3000:3000"
create-next-app
$ docker-compose run --rm app npx create-next-app sample-app
起動
$ docker-compose up
ホットリロード有効化と動作速度
今回試した限りでは、Next.jsをDocker上で動かすとホットリロードが無効になっていました。
- next.config.jsファイル
- docker-compose.yml ファイル
のいずれかに設定を追加することで、ホットリロードを有効化することができます。
next.config.jsの場合、「webpackDevMiddleware: config => {},」の部分を追記します。
$ cat sample-app/next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
webpackDevMiddleware: config => {
config.watchOptions = {
poll: 800,
aggregateTimeout: 300,
}
return config
},
}
module.exports = nextConfig
docker-compose.ymlの場合、「WATCHPACK_POLLING=true」の設定を追加します。
$ cat docker-compose.yml
version: '3'
services:
app:
build:
context: .
dockerfile: Dockerfile
volumes:
- ./:/usr/src/app
environment:
- WATCHPACK_POLLING=true
command: sh -c "cd sample-app && npm run dev"
ports:
- "3000:3000"
1行追記するだけでいいので、docker-compose.ymlで設定するほうが楽です。
しかし、いずれの方法で有効化した場合にも、速度面で難があります。
計測したところ、ファイルを編集して変更結果がブラウザ上に反映されるまでに10-15秒かかりました。
ホットリロードは頻繁に使うので、毎回この待ち時間が発生するのは辛いです。
遅い原因
動作が遅いのはDockerからMacのファイルシステムへのアクセスが遅いことが原因のようです。
- File system performance improvements · Issue #1592 · docker/for-mac (github.com)
- [Docker Desktop] Improve Mac File system performance · Issue #7 · docker/roadmap (github.com)
Windows + WSL2の環境でもWSL2からWindowsのファイルシステムへのアクセスが遅かったので、おそらく同じような状況なのでしょう。
(続き)Windows+WSL2でReactの開発環境を作った · kapieciiのブログ
改善するためには、Docker Desktopで新しく設定が追加された「Virtiofs」を有効化するのが良さそうです。
- 【超重要な追記あり】Docker Desktop for Macを使ってる人はみんな今すぐvirtiofsを使うんだ! - Sweet Escape (keisuke69.net)
- virtiofs - shared file system for virtual machines (virtio-fs.gitlab.io)
しかしDocker Desktopは先日有料化されたこともあり、ライセンスの問題ですぐには使えません。
また、今回のように「ちょっと試したい」「短期間だけ使いたい」という用途にも不向きです。
定常的に業務で使っている同僚は会社に申請してライセンスを購入していますが、私はスポットでしか使わないのでRancher Desktopを使っています。
Docker Desktop、無料で使える猶予期間が終了 従業員数250人以上、年間売り上げ1000万ドル以上の組織は有料に - ITmedia NEWS
DockerのNamed Volumeを使う方法もあるようですが、前述のVirtiofsと比べると効果が限定的なようです。
Macで使うVS CodeとRemote Containerの性能を大幅改善 - Sweet Escape (keisuke69.net)
公式情報(Next.js+Docker)
Next.jsの公式からも、Dockerに関する情報が公開されています。
Deployment | Next.js (nextjs.org)
Dockerを使った環境について議論しているスレッド
What is the best way to use NextJS with docker? · Discussion #16995 · vercel/next.js (github.com)
Examples With Docker
next.js/examples/with-docker at canary · vercel/next.js (github.com)
Examples With Docker Compose
next.js/examples/with-docker-compose at canary · vercel/next.js (github.com)
開発環境として「With Docker Compose」が公開されていたので試してみましたが、ホットリロードにかかる時間は同じでした。
参照URL
今回の検証で参照させていただいたURLはこちら。
情報を公開してくださっている皆様、ありがとうございます。
- Deployment | Next.js (nextjs.org)
- What is the best way to use NextJS with docker? · Discussion #16995 · vercel/next.js (github.com)
- next.js/examples/with-docker at canary · vercel/next.js (github.com)
- DockerでNext.jsの環境構築をする (zenn.dev)
- Gitの一部のディレクトリだけ取得する方法 - Qiita
- 【超重要な追記あり】Docker Desktop for Macを使ってる人はみんな今すぐvirtiofsを使うんだ! - Sweet Escape (keisuke69.net)
- docker+next.jsで初期環境構築できたので手順のメモを残しておく | laby’s Tech Blog (laby-tech.com)
- dockerでcreate-next-appしたらglob error Error: EACCES: permission deniedが出た | laby’s Tech Blog (laby-tech.com)
最後に
というわけで最初の結論の通り、Next.jsアプリはローカルで開発することにしました。 将来ファイルシステムへのアクセス速度が改善したら、この記事の続きから再チャレンジしてみようと思います。