docker icon
Docker
---
title: "Next.jsアプリをDockerで動かす!環境差異に悩まないための実践ガイド"
excerpt: "開発環境と本番環境の違いに悩んだことはありませんか?Next.jsとDockerを組み合わせることで、どの環境でも同じように動くアプリケーションを作れます。初心者向けに基本から丁寧に解説します。"
date: "2025-01-24"
---

## 環境の違いで動かない問題、経験ありませんか?

こんにちは、とまだです。

「ローカルでは動くのに、本番では動かない...」

みなさん、こんな経験はありませんか?

開発メンバーによってNode.jsのバージョンが違う。
npmとyarnが混在している。
OSの違いでパッケージがうまく動かない。

こういった環境差異の問題は、本当によくあるトラブルです。

今回は、Next.jsアプリケーションをDockerで動かす方法を解説します。

この記事を読めば、環境差異に悩まされることなく、安定した開発ができるようになります。

## そもそもDockerとは?

Dockerは「コンテナ」という技術を使ったツールです。

コンテナって聞くと難しそうですよね。
でも、実はとてもシンプルな仕組みなんです。

例えば、お弁当箱を想像してみてください。

お弁当箱の中には、ごはんやおかずが入っています。
そして、そのお弁当箱はどこに持っていっても同じ中身です。

Dockerも同じような考え方です。

アプリケーションと実行環境を「コンテナ」という箱に入れます。
その箱は、どのコンピュータでも同じように動きます。

つまり、環境の違いを気にする必要がなくなるんです。

## Next.jsとDockerの相性が良い理由

Next.jsは、フロントエンドとバックエンドが一体になったフレームワークです。

通常のReactアプリと違って、サーバーサイドの処理もあります。
APIルートも含まれています。

こういった複雑な構成だからこそ、Dockerが活躍します。

なぜなら、すべての環境設定をコンテナに含められるからです。

Node.jsのバージョンも固定できます。
必要なパッケージも一緒に管理できます。
環境変数の設定も統一できます。

また、チーム開発でも大きなメリットがあります。

新しいメンバーが参加しても、Dockerさえあれば同じ環境を構築できます。
「動かない」というトラブルが激減します。

さらに、本番環境へのデプロイも簡単になります。

## 実際にDockerfileを書いてみよう

それでは、実際のDockerfileを見てみましょう。

以下が、Next.jsアプリ用のシンプルなDockerfileです。

```dockerfile
# Node.jsのイメージを使用
FROM node:18-alpine

# 作業ディレクトリを設定
WORKDIR /app

# package.jsonとpackage-lock.jsonをコピー
COPY package*.json ./

# 依存関係をインストール
RUN npm install

# アプリケーションのソースコードをコピー
COPY . .

# Next.jsをビルド
RUN npm run build

# ポート3000を公開
EXPOSE 3000

# アプリケーションを起動
CMD ["npm", "start"]

このDockerfileは、シンプルですが基本的な構成です。 各行で何をしているか、簡単に説明します。

FROMでは使用するベースイメージを指定します。 WORKDIRで作業場所を決めます。 COPYRUNでファイルのコピーとコマンド実行を行います。

ただし、このままだとイメージサイズが大きくなりがちです。

そこで、次はもっと効率的な方法を紹介します。

マルチステージビルドで軽量化しよう

マルチステージビルドという技術を使うと、イメージを軽量化できます。

これは、料理で例えると「下ごしらえ」と「盛り付け」を分ける感じです。

下ごしらえの段階では、包丁やまな板など色々な道具を使います。 でも、最終的な料理には道具は含まれませんよね。

同じように、ビルドに必要なツールと実行に必要なものを分けます。

# ビルド用ステージ
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build

# 実行用ステージ
FROM node:18-alpine
WORKDIR /app

# ビルド成果物だけをコピー
COPY --from=builder /app/package*.json ./
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/node_modules ./node_modules

EXPOSE 3000
CMD ["npm", "start"]

ビルド用ステージでは、コンパイルに必要なツールを使います。 実行用ステージでは、必要最小限のファイルだけを持ってきます。

結果として、イメージサイズが大幅に削減されます。

デプロイ時間も短縮されますし、セキュリティ面でも有利です。

環境変数の扱い方

Next.jsでは、環境変数を使うことが多いですよね。

APIキーやデータベースの接続情報など。 これらをDockerでどう扱うか、悩む方も多いです。

Docker Composeを使うと、環境変数の管理が楽になります。

version: '3.8'
services:
  nextjs:
    build: .
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=${DATABASE_URL}
    env_file:
      - .env.production

.env.productionファイルに本番用の環境変数を書きます。 Docker Composeがそれを読み込んで、コンテナに渡してくれます。

ただし、秘密情報の扱いには注意が必要です。

GitHubなどにアップロードしないよう、.gitignoreに追加しましょう。 本番環境では、環境変数管理サービスを使うことをおすすめします。

よくあるトラブルと解決方法

Docker化する際によくある問題をいくつか紹介します。

ポートが使えない問題

「ポート3000はすでに使用中です」というエラー。

これは本当によく遭遇します。

解決方法は簡単です。 Docker Composeで別のポートにマッピングします。

ports:
  - "3001:3000"  # ホストの3001番をコンテナの3000番に

ビルドが遅い問題

毎回全部をビルドし直すと、時間がかかります。

Dockerのキャッシュを活用しましょう。

package.jsonが変更されていない限り、npm installはキャッシュされます。 だから、package.jsonを先にコピーするのが重要なんです。

ホットリロードが効かない問題

開発環境では、ファイルを変更したら自動で反映してほしいですよね。

volumeを使って、ローカルのファイルをマウントします。

volumes:
  - ./src:/app/src
  - ./pages:/app/pages

これで、ファイルを編集すると即座に反映されます。

まとめ

Next.jsとDockerを組み合わせることで、環境差異の問題を解決できます。

マルチステージビルドで軽量化もできます。 環境変数の管理もDocker Composeで簡単になります。

最初は難しく感じるかもしれません。 でも、基本的な仕組みを理解すれば、それほど複雑ではありません。

まずはシンプルなDockerfileから始めてみてください。 慣れてきたら、徐々に最適化していけばOKです。

環境構築で悩む時間を減らして、開発に集中できる環境を作りましょう!

共有:

著者について

とまだ

とまだ

フルスタックエンジニア

Learning Next の創設者。Ruby on Rails と React を中心に、プログラミング教育に情熱を注いでいます。初心者が楽しく学べる環境作りを目指しています。

著者の詳細を見る →