0
1

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環境をDocker上に作成する dev & build対応

Posted at

[公式]: Next.js × Docker 本番環境サンプル

Next.jsをDocker上で動かす

こちらの記事ではNext.js開発環境をDocker上に作成するための手順を紹介いたします。

GitHub: 今回のサンプルコードはこちら

要点は以下の通りです。

  • Dockerとローカルそれぞれでnode_modulesなど必要モジュールを用意する
  • 開発時はsrcディレクトリをバインドマウント → ホットリロードを可能にする
  • 同環境で本番ビルドと実行ができる

問題点があればぜひご指摘ください

1. プロジェクト作成

まずはテンプレートの作成です。

npx create-next-app@latest

選択肢は全てYesにしました。
今回の構成と同じにする場合は、srcを使用する選択をしてください。

スクリーンショット 2024-12-21 022244.png

2. 構成ファイルの追加

今回は追加でDockerの設定ファイルを作成します。
頻繁に使用する開発(デフォルト)用と、
たまに使用する本番環境用とで、
それぞれのDockerfileとcompose.yamlを用意します。
共通になりますが、.dockerignoreも作成します。

共通ファイル

.dockerignore

build時、コンテクスト(構築用ファイル群)に含めたくないものを指定します。
ここに含めたものは、COPYなどの対象になりません。
必要に応じて追加します。

.git
.gitignore
.dockerignore
Dockerfile*
*.yaml
.md

.next
.swc
node_modules


開発環境実行用

develop.sh

./develop.shとして実行すると起動します。
ファイルの実行権限が必要です。
ない場合はchmod u+x ./develop.shなどで追加します。

-fオプションによってcomposeファイルが組み合わされて実行されます。
./develop.sh bと半角空白+bをつけて実行すると再ビルドが走ります。
本番環境実行直後、開発に戻る時はそのように実行するとよいです。

#!/bin/bash

if [ "$1" = "b" ]; then
  docker compose -f compose.yaml build
fi
docker compose -f compose.yaml up

Dockerfile

FROM node:22.11.0-slim
ENV NODE_ENV=development
USER node
WORKDIR /app
COPY package*.json ./
RUN npm ci

COPY --chown=node:node ./*.*js* ./*.ts ./
COPY --chown=node:node ./public ./public

ENV HOSTNAME="0.0.0.0"

CMD ["npm", "run", "dev"]
コードの補足
  • npm ci
    node_modulesを一度消してからpackage-lock.jsonを書き換えずに依存関係をインストールします。
    package-lock.jsonの通りに再現するためのコマンドです。

  • COPY
    ./にある.js, .json, .mjs, .tsをコピーします。
    ./publicも同様です。他のディレクトリを作成した場合は追記してください。

補足事項

追加のインストールが必要な時は、ローカルでインストールしてから、Dockerの再ビルドを行います。

npm install  <モジュール名> <モジュール名> ...
↓
↓
./develop.sh b

これによってローカルのモジュール更新 + package-lock.jsonの更新によりDockerのビルド時に更新が入ります。

また、「/」配下の各設定ファイルはマウント非対象のため、これらを変更した場合も再ビルドが必要になります。

compose.yaml

dev用の項目を書きます。
prodと共通の項目があってもどちらにも書きます。
他のコンテナなどを追加する場合も同様です。

services:
  nextjs:
    build:
      context: .
      dockerfile: Dockerfile
    container_name:
      nextjs-dev
    ports:
      - "3000:3000"
    volumes:
      - ./src/:/app/src/

本番環境実行用

production.sh

./production.shとして実行すると起動します。
ファイルの実行権限が必要です。
ない場合はchmod u+x ./production.shなどで追加します。

#!/bin/bash

if [ "$1" = "b" ]; then
  docker compose -f compose.prod.yaml build
fi
docker compose -f compose.prod.yaml up

Dockerfile.prod

本番実行の時はcompose.prod.yaml内の指定でこちらが選択されます。
公式のものを多少削って利用しております。

FROM node:22.11.0-slim AS base

FROM base AS deps
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm ci --include=dev

FROM base AS builder
ENV NODE_ENV=production
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM base AS runner
ENV NODE_ENV=production
WORKDIR /app
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
COPY --from=builder --chown=nextjs:nodejs /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT=3000
ENV HOSTNAME="0.0.0.0"

CMD ["node", "server.js"]

compose.prod.yaml

prod用の項目を書きます。
devと共通の項目があってもどちらにも書きます。
他のコンテナなどを追加する場合も同様です。

services:
  nextjs:
    build:
      context: .
      dockerfile: Dockerfile.prod
    container_name:
      nextjs-prod
    ports:
      - "3000:3000"

next.config.ts

1行追加します。
本番環境に最適化されたコードが出力されるそうです。

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
+  output: "standalone",
};

export default nextConfig;

以上です!

最後まで見て頂き、ありがとうございます!

再ビルドが必要なタイミング

  • モジュール追加後
  • develop ↔ production環境を切り替える時
  • 設定ファイルに変更を加えた時

今回はDockerに関する部分を紹介させていただきましたが、他にもESLintの設定などもありますね。

Dockerのドキュメントを眺めながら作ってみました。
一応やりたいことができて満足しましたが、もっといいやり方があるなどあればぜひ教えて頂きたいです!

この方法では、AWSのEC2インスタンス無料枠:t2.micro内でのビルドはcpu使用量が厳しくて難しいようでした。
(ソースコードの量や使用モジュールの量が少なければ大丈夫です)
今回のサンプルコードの状態でcpu最大使用率68%のようです。(メトリクス参照)

ビルドができれば接続可能です!
スクリーンショット 2024-12-22 214249.png

シェルスクリプト作成の参考にさせて頂きました!

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?