0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsの開発環境を公式ドキュメントを参照しながら構築する

Last updated at Posted at 2025-11-01

はじめに

この記事について

この記事はWeb開発初心者の私がアドベントカレンダーの力を借りて勉強を進めるために書いています。
そのため、ほぼ忘備録的に書いているので、記事の内容については保証できません。
あと、Next.jsのDockerfileなどの作成はClaude Codeを使いながら実施しているので、公式ドキュメントオンリーではないです。

動作環境

  • OS: Windows 11 Home 25H2
  • コードエディタ: VSCode ver1.105.1
  • Docker Desktop on Windows: 4.49.0
  • Node.js: v24.11.0(LTS)
  • Next.js: v16.0.1

Docker Desktopのインストール

なぜDockerなのか

Node.jsのダウンロードをする際に、一番トップにDockerでのダウンロード方法が表示されたので、勝手にDockerを使うのが推奨なのだと判断しました。

Dockerの公式ドキュメントのインストール手順を実行

今回はDocker Desktop Installer.exe でインストールします。
インストール後に初回起動でログインする必要があります。今回は個人開発なので、personalタブ側でGithubアカウントを使ってログインしました。

Node.jsのインストール

Node.jsのパッケージマネージャーについて

公式でpnpmを推奨しているので、本記事内ではpnpmを使用していきます。

参考URL

Node.jsの公式ドキュメントのインストール手順を実行

Dockerがインストール出来ていたら、VSCode上でターミナルを起動して以下のPowerShellコマンドを実行

# Node.jsのDockerイメージを取得する:
docker pull node:24-alpine

# Node.jsのコンテナーを作成しシェルを起動する:
docker run -it --rm --entrypoint sh node:24-alpine

# Node.jsのバージョンを確認する:
node -v # "v24.11.0"が表示される。

# pnpmをダウンロードしてインストールする:
corepack enable pnpm

# pnpmのバージョンを確認する:
pnpm -v

Dockerコンテナ起動時の各コマンドの意味

docker run -it --rm --entrypoint sh node:24-alpine

意味:

  • docker run: コンテナを作成して起動
  • -it: 2つのオプションの組み合わせ
    • -i (interactive): 標準入力を開いたままにする
    • -t (tty): 疑似ターミナルを割り当てる
    • → この2つで対話的にコンテナ内でコマンド操作できる
  • --rm: コンテナ終了時に自動的にコンテナを削除(クリーンアップ)
  • --entrypoint sh: デフォルトの起動コマンドを上書きしてsh(シェル)を起動
    • 通常Node.jsコンテナはnodeコマンドで起動するが、これによりシェルで起動
  • node:24-alpine: 使用するイメージ名

結果

このコマンドを実行すると、Node.js 24がインストールされたAlpine Linuxのシェルに入り、自由にコマンドを実行できる環境になります。コンテナから抜ける(exitまたはCtrl+D)と、コンテナは自動的に削除されます。

Next.js用のDockerfile,docker-compose.ymlを作成

Dockerfile

FROM node:24-alpine AS base
# pnpmをインストール
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && \
    corepack prepare pnpm@latest --activate

# 依存関係インストール専用ステージ
FROM base AS deps
WORKDIR /app
# マウントキャッシュを使用してさらに高速化
COPY package.json pnpm-lock.yaml* ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
    pnpm install --frozen-lockfile

# 開発環境用ステージ
FROM base AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["pnpm", "run", "dev"]

docker-compose.yml

name: my-nextjs-app

services:
  nextjs:
    container_name: nextjs-dev
    build:
      context: ..
      dockerfile: docker/Dockerfile
      target: dev
    ports:
      - "3000:3000"
    volumes:
      - ..:/app
      - /app/node_modules
      - /app/.next
      # pnpm特有: pnpmのストアをキャッシュ
      - pnpm-store:/pnpm/store
    environment:
      - NODE_ENV=development
      - WATCHPACK_POLLING=true
    stdin_open: true
    tty: true
    restart: unless-stopped
    networks:
      - nextjs-network

volumes:
  pnpm-store:

networks:
  nextjs-network:
    driver: bridge

Dockerfileの解説

FROM node:24-alpine AS base
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable && \
    corepack prepare pnpm@latest --activate

意味:

  • ベースとなるイメージを定義
  • AS baseで「base」という名前をつけて、後で参照できるようにする
  • corepack: Node.js 16以降に含まれるパッケージマネージャー管理ツール
  • pnpmを有効化

FROM base AS deps
WORKDIR /app
COPY package.json pnpm-lock.yaml* ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store \
    pnpm install --frozen-lockfile

意味:

  • FROM base AS deps: baseから新しいステージ「deps」を作成(依存関係インストール専用)
  • WORKDIR /app: 作業ディレクトリを/appに設定
  • COPY package.json pnpm-lock.yaml* ./: package.jsonpnpm-lock.yaml(無くてもよい)だけをコピー
  • --mount=type=cache: Dockerのビルドキャッシュマウント機能
  • --frozen-lockfile: pnpm-lock.yamlを更新せずにインストール(npm ciと同等)

FROM base AS dev
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
EXPOSE 3000
CMD ["pnpm", "run", "dev"]

意味:

  • FROM base AS dev: 開発環境用のステージを作成
  • COPY --from=deps /app/node_modules ./node_modules: depsステージからnode_modulesをコピー
  • COPY . .: すべてのソースコードをコピー
  • EXPOSE 3000: 3000番ポートを公開
  • CMD ["pnpm", "run", "dev"]: コンテナ起動時のデフォルトコマンド

docker-compose.ymlの解説

各セクションの意味

name: my-nextjs-app    # プロジェクト全体の名前
services:              # コンテナの定義
volumes:               # 永続化データの定義
networks:              # ネットワークの定義

servicesセクションの詳細

services:
  nextjs:                        # docker compose run実行時のサービス名
    container_name: nextjs-dev   # コンテナに付ける名前
    build:
      context: ..                # Dockerfileをdockerディレクトリに格納するので、親ディレクトリの場所
      dockerfile: docker/Dockerfile  # Dockerfileを指定
      target: dev                # Dockerfileの「dev」ステージを使用
    ports:
      - "3000:3000"              # ポートのマッピング。Windowsの3000番ポートをコンテナの3000番に転送
    volumes:
      - ..:/app                  # 親ディレクトリ(Windows側)をコンテナの`/app`にマウント。Windows側でファイルを編集すると、リアルタイムでコンテナ内にも反映
      - /app/node_modules        # コンテナ内の/app/node_modulesを優先する
      - /app/.next               # Next.jsのビルドキャッシュをコンテナ内だけで管理
      - pnpm-store:/pnpm/store   # pnpmのパッケージストア(キャッシュ)を永続化。名前付きボリュームを使用
    environment:
      - NODE_ENV=development     # Node.jsに「開発モード」であることを伝える。開発用の便利な機能やエラー表示が有効になる
      - WATCHPACK_POLLING=true   # ファイル変更の監視方法を「ポーリング」に変更。Windows特有の設定
    stdin_open: true             # docker run の -i に相当。標準入力を開いたまま
    tty: true                    # docker run の -t に相当。疑似ターミナルを割り当て
    restart: unless-stopped      # コンテナの再起動ポリシー:手動停止しない限り常に再起動
    networks:
      - nextjs-network           # このコンテナが接続するネットワークを指定。同じネットワークのコンテナ同士が通信できるようになる

volumesセクションの詳細

volumes:
  pnpm-store:  # 名前付きボリュームを定義。Dockerが管理する永続化ストレージ。複数のコンテナでデータを共有できる

networksセクションの詳細

networks:
  nextjs-network:    # カスタムネットワークを定義
    driver: bridge   # 最も一般的なネットワークドライバ。同じホスト内のコンテナ同士を接続

実際の開発フロー

# 1. Windows側でプロジェクト作成
C:\Users\YourName> mkdir my-nextjs-app
C:\Users\YourName> cd my-nextjs-app
C:\Users\YourName\my-nextjs-app> mkdir docker
C:\Users\YourName\my-nextjs-app> cd docker

# 2. Dockerfile, docker-compose.ymlを作成(Windows側)

# 3. Next.jsプロジェクトをpnpmで作成(注意!!)
docker compose run --rm nextjs pnpm create next-app . --typescript --tailwind --app

# 4.開発サーバー起動
docker compose up

# 5. Windows側でVS Codeなどを開く
# src/app/page.tsx を編集
# → 保存すると自動的にブラウザが更新される!

# 6.開発サーバー終了
docker compose down

躓いた箇所

# 3. Next.jsプロジェクトをpnpmで作成
docker compose run --rm nextjs pnpm create next-app . --typescript --tailwind --app

# エラー発生
failed to solve: failed to compute cache key: failed to calculate checksum of ref ~~~: "/pnpm-lock.yaml": not found

pnpm-lock.yamlが見つからずエラー発生した。
今回は初回作成用のDockerfile.initとdocker-compose.init.ymlを作成して、next.jsプロジェクトを作ることにした。(いい方法があればコメントお願いします。)

Dockerfile.init

FROM node:24-alpine

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"

RUN corepack enable && \
    corepack prepare pnpm@latest --activate

WORKDIR /app

docker-compose.init.yml

name: my-nextjs-app

services:
  nextjs:
    build:
      context: ..
      dockerfile: docker/Dockerfile.init
    volumes:
      - ..:/app
      - pnpm-store:/pnpm/store

volumes:
  pnpm-store:

初回用コマンド

docker compose -f docker-compose.init.yml run --rm nextjs sh
pnpm create next-app ./temp-next --typescript --tailwind --app
✔ Which linter would you like to use? › ESLint
✔ Would you like to use React Compiler? … Yes
✔ Would you like your code inside a `src/` directory? … No
✔ Would you like to use Turbopack? (recommended) … Yes
✔ Would you like to customize the import alias (`@/*` by default)? … No
rsync -av temp-next/ .
rm -rf temp-next

開発時に使用するDockerコマンド

# ビルドだけ行う
docker compose up --build

# 開発サーバー起動中の別ターミナルで
docker compose exec nextjs pnpm add axios

# または一度だけ実行する場合
docker compose run --rm nextjs pnpm add axios

# 依存関係の更新
docker compose exec nextjs pnpm update

# パッケージの削除
docker compose exec nextjs pnpm remove axios

# scripts実行
docker compose exec nextjs pnpm run build

# コンテナ内に入って確認
docker compose run --rm nextjs sh

VSCode拡張機能のインストール

  • Dev Containers:コンテナ内で開発する(これが無いとts2307エラーが解決しない)

Dev Containersの実行手順

  1. devcontainer.jsonを作成
    my-nextjs-app/.devcontainer/devcontainer.json
  2. Ctrl+Shift+P でコマンドパレットを開く
  3. Dev Containers: Reopen in Container を選択

devcontainer.json

{
  "name": "Next.js Development",
  "dockerComposeFile": "../docker/docker-compose.yml",
  "service": "nextjs",
  "workspaceFolder": "/app",

  "overrideCommand": true,
  
  "initializeCommand": "docker volume create pnpm-store",
  
  "customizations": {
    "vscode": {
      "extensions": [
        "dbaeumer.vscode-eslint",
        "esbenp.prettier-vscode",
        "bradlc.vscode-tailwindcss",
        "formulahendry.auto-rename-tag",
        "ms-azuretools.vscode-docker"
      ],
      "settings": {
        "terminal.integrated.defaultProfile.linux": "bash",
        "editor.formatOnSave": true,
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "typescript.tsdk": "node_modules/typescript/lib"
      }
    }
  },
  
  "forwardPorts": [3000],
  
  "postCreateCommand": "pnpm install",
  
  "remoteUser": "node"
}

躓いた箇所

VSCodeで開いていたフォルダが一階層上だったため、.devcontainer/devcontainer.jsonを正しく読み込めず、テンプレートコンテナを起動してしまった。

おわりに

Next.jsで開発を始めたいのに、環境を整える部分で知らないことが沢山出てきました。
今後もそういった知らない前提知識が出てくると思うので、ワクワクしています。

一応計9年くらい開発経験(車載系で7年/製造業オープン系で2年)があるはずなのに、WEB系になると初心者同然となってしまうのが、キャリアチェンジの難しさを感じました。

開発者人生で初めて記事を書いてみたので、色々拙い部分があると思いますが感想やご指摘お待ちしています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?