DockerでNext.jsの開発環境を作ったがローカルで開発することにした

Jul 24, 2022 21:40 · 2047 words · 5 minute read Docker Next.js

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のファイルシステムへのアクセスが遅いことが原因のようです。

Windows + WSL2の環境でもWSL2からWindowsのファイルシステムへのアクセスが遅かったので、おそらく同じような状況なのでしょう。

(続き)Windows+WSL2でReactの開発環境を作った · kapieciiのブログ

改善するためには、Docker Desktopで新しく設定が追加された「Virtiofs」を有効化するのが良さそうです。

しかし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はこちら。
情報を公開してくださっている皆様、ありがとうございます。

最後に

というわけで最初の結論の通り、Next.jsアプリはローカルで開発することにしました。 将来ファイルシステムへのアクセス速度が改善したら、この記事の続きから再チャレンジしてみようと思います。

tweet Share