Next.js

Docker でNext.jsの環境構築する

8
  • 環境構築
  • Docker

ホストに Node.js を入れず、Docker だけで Next.js(App Router)のプロジェクト作成から next dev 起動までやります。create-next-app@latest を使うので、執筆時点では Next.js 16 系が入ります(15 系でも手順はほぼ同じです)。

Docker Desktop か Docker Engine + Compose が動いていれば足ります。プロジェクトがまだない前提で書いています。

ひとつだけ順番に注意があります。空の作業フォルダを作って create-next-app を先に回し、そのあとで Dockerfile などを足すこと。Docker 用ファイルを先に置くと create-next-app .contains files that could conflict で止まります。

参考: Next.js — Deploying with Docker · Docker Docs — Compose


目次

  1. なぜ Docker で開発するか
  2. 始める前に
  3. 全体の流れ
  4. プロジェクトをコンテナで作る
  5. 開発用 Dockerfile
  6. docker-compose.yml
  7. .dockerignore
  8. 環境変数
  9. 起動と確認
  10. うまくいかないとき

なぜ Docker で開発するか

Node のバージョンや OS がバラバラだと「自分の PC では動く」が出ます。node:22-alpine のようなイメージで揃えておけば、docker compose up で同じ環境を再現しやすくなります。ホストのグローバル npm ともぶつかりにくいです。

ここで作るのは 開発用だけ です。コンテナ内で next dev を動かし、ソースはボリュームマウントでホットリロードさせます。Next.js カテゴリの環境構築は ローカル開発に閉じ、本番イメージ・クラウドデプロイは扱いません。Next.js 16 系だと起動ログに Turbopack と出ることがありますが、気にしなくて大丈夫です。


始める前に

  • Docker が起動している(Desktop でも Engine でも可)
  • 作業フォルダはDockerfileREADME.md も置かない)
  • フォルダ名は _ で始めない(npm の命名規則で弾かれる)
  • パスに日本語やスペースがない方が無難(例: C:\projects\my-next-app
  • ポート 3000 が空いている(塞がっていれば 3001:3000 などに変える)

create-next-app が終わったら package.jsonpackage-lock.json があることを確認してから Docker ファイルを足します。docker compose up の前に .env.example(Git 用テンプレ).env.local(手元・コンテナ用、空で可) を用意します。


全体の流れ

flowchart LR A["1. 空フォルダ"] --> B["2. create-next-app"] B --> C["3. Docker ファイル追加"] C --> D["4. .env.example / .env.local"] D --> E["5. docker compose up"]

Docker は2回だけ出てきます。ここを混同するとハマりやすいです。

段階 コマンド Dockerfile 目的
プロジェクト生成 docker run + node:22-alpine 不要 空フォルダに Next.js を作る
日常の開発 docker compose build / up 自分で書く next dev をホットリロード付きで動かす

docker run は一時コンテナでコマンドを1回実行するだけです。docker compose は後から足した Dockerfiledocker-compose.yml を読みます。ホストに Node.js も create-next-app も要りません。初回は node:22-alpine が Docker Hub から取られます。

完成後のディレクトリはこんな感じです。

my-next-app/  Dockerfile  docker-compose.yml  .dockerignore  .env.example  .env.local  package.json  src/    app/      page.tsx      layout.tsx

プロジェクトをコンテナで作る

空のフォルダで create-next-app を実行します。App Router・TypeScript・src/ 構成にしています。

npx --yes は npx 側の Ok to proceed? (y) を、create-next-app--yes はテンプレート選択の対話をスキップします。両方付けておくと止まりにくいです。

PowerShell(Windows)

mkdir my-next-appcd my-next-appdocker run --rm -it -v ${PWD}:/app -w /app node:22-alpine sh -c "npx --yes create-next-app@latest . --typescript --eslint --app --src-dir --no-tailwind --use-npm --yes"

Git Bash(Windows)

Git Bash だと -w /appC:/Program Files/Git/app に化けることがあります。PowerShell 用をそのままコピーしないでください。

mkdir my-next-app && cd my-next-appMSYS_NO_PATHCONV=1 docker run --rm -it \  -v "$(pwd -W):/app" \  -w /app \  node:22-alpine \  sh -c "npx --yes create-next-app@latest . --typescript --eslint --app --src-dir --no-tailwind --use-npm --yes"

bash(macOS / Linux)

mkdir my-next-app && cd my-next-appdocker run --rm -it -v "$(pwd):/app" -w /app node:22-alpine sh -c "npx --yes create-next-app@latest . --typescript --eslint --app --src-dir --no-tailwind --use-npm --yes"

ホストに Node.js があるなら、空フォルダで次を打っても同じです。以降の Docker 手順は共通です。

npx --yes create-next-app@latest . --typescript --eslint --app --src-dir --no-tailwind --use-npm --yes

主なフラグ: --app(App Router)、--src-dirsrc/ 配下)、--no-tailwind--use-npmpackage-lock.json 生成)、--yes(対話スキップ)。

終わると package.jsonsrc/app/page.tsx などがホスト側にできます。npm install はコンテナ内で走ります。

ls package.json, src/app/page.tsx

この時点でブラウザを開く必要はありません。次に Docker ファイルを足します。


開発用 Dockerfile

package.jsonpackage-lock.json が揃ったら、ルートに Dockerfile を置きます。

# Dockerfile(開発用)FROM node:22-alpineWORKDIR /appCOPY package.json package-lock.json* ./RUN npm ciCOPY . .EXPOSE 3000CMD ["npm", "run", "dev", "--", "-H", "0.0.0.0", "-p", "3000"]

COPY package.json を先にしておくと、依存が変わらない限りビルドキャッシュが効きます。

CMD-H 0.0.0.0 は外さないでください。デフォルトの localhost だけだと、コンテナの外(ホストのブラウザ)から繋がりません。

pnpm / yarn を使う場合は COPY と install コマンドを合わせて変えてください。


docker-compose.yml

ソースをマウントして、保存のたびにホットリロードさせます。

# docker-compose.ymlservices:  web:    build:      context: .      dockerfile: Dockerfile    ports:      - "3000:3000"    volumes:      - .:/app      - /app/node_modules      - /app/.next    environment:      - NODE_ENV=development      - WATCHPACK_POLLING=true    env_file:      - .env.local
  • .:/app — ホストのソースをコンテナに同期
  • /app/node_modules — ホストとコンテナでバイナリが食い違うのを防ぐ
  • /app/.next — ビルドキャッシュの競合を減らす
  • WATCHPACK_POLLING=true — Windows / macOS で変更が拾えないときの保険

env_file.env.local があるときだけ読み込まれます。次のセクションで空ファイルを作ってから初回起動してください。

Windows の Docker Desktop だと、ポーリングがないと変更検知が遅く感じることがあります。


.dockerignore

node_modules.next.git.gitignoreREADME.mdDockerfiledocker-compose.yml.env*.localnpm-debug.log*

.env.local をイメージに焼き込まないためです。値は実行時に env_file で渡します。


環境変数

ファイル Git 役割
.env.example 入れる キー名だけのテンプレ。チーム共有用
.env.local 入れない 実際の値。手元とコンテナ(env_file)用

.env.example(キー名だけ)

# 共有用テンプレ(値は空またはダミー)NEXT_PUBLIC_SITE_URL=API_SECRET=

PowerShell

@'# 共有用テンプレ(値は空またはダミー)NEXT_PUBLIC_SITE_URL=API_SECRET='@ | Set-Content -Path .env.example -Encoding utf8

bash / Git Bash

cat > .env.example << 'EOF'# 共有用テンプレ(値は空またはダミー)NEXT_PUBLIC_SITE_URL=API_SECRET=EOF

.env.local(手元の値・空でも可)

PowerShell

New-Item -Path .env.local -ItemType File -Force

bash / Git Bash

touch .env.local

値を足すときの例:

NEXT_PUBLIC_SITE_URL=http://localhost:3000API_SECRET=dev-only-secret

NEXT_PUBLIC_ だけがクライアントに入る点は、ホストで next dev するときと同じです。.env.local は Git に入れません。clone した人は .env.example をコピーして .env.local を作り、値を埋めます。

cp .env.example .env.local

PowerShell:

Copy-Item .env.example .env.local

コピー後、.env.local に開発用の値を書いてください。


起動と確認

プロジェクトルートで:

docker compose builddocker compose up

http://localhost:3000 を開き、src/app/page.tsx を編集して保存。数秒で画面が変われば OK です。ログに ReadyGET / 200 が出ていれば問題ありません。

止めるときは Ctrl+C のあと docker compose down。コンテナとボリュームごと消すなら docker compose down -vnode_modules 入りの匿名ボリュームも消えるので、次回は再インストールが走ります)。

既に create-next-app 済みのプロジェクトなら、Docker ファイルを足すところから同じ構成にできます。


うまくいかないとき

症状 対処
Ok to proceed? (y) で止まる npx --yes を付ける
create-next-app が対話で止まる 末尾に --yes を付ける
contains files that could conflict 空フォルダで CNA を先に。Docker ファイルは後
name cannot start with an underscore フォルダ名を my-next-app などに変える
Git Bash で .../Git/app MSYS_NO_PATHCONV=1-v "$(pwd -W):/app"
docker compose build 失敗 先に create-next-app を完了させる
env_file エラー .env.local を空で作る
ブラウザで繋がらない CMD-H 0.0.0.0 があるか確認
保存しても反映されない WATCHPACK_POLLING=true
node_modules がおかしい 匿名ボリューム /app/node_modules を確認
ポート使用中 ports: "3001:3000" などに変更

Windows なら WSL2 バックエンドの Docker Desktop の方が、ボリューム I/O とファイル監視が安定しやすいです。


関連: Docker — Compose file reference

シェア