この記事では、Dockerファイルを使い、Next.jsアプリケーションをコンテナ化、デプロイする方法をご紹介します。自動デプロイ機能を利用してNext.jsアプリをKinstaにデプロイすることもできます。

Dockerでは、アプリケーションとその環境、依存関係の隔離されたコンテナへのパッケージ化が行われます。コンテナはLinuxで動作するアプリケーションで構成されます。Dockerイメージは言うなればコンテナのブループリントであり、コンテナはイメージの実行インスタンスとして機能します。

アプリケーションをコンテナ化するには、Dockerfileを通じて宣言的に設計を行います。そして、Dockerがこのファイルで定義されたスクリプトを読み込み、アプリケーションのビルドとデプロイを担います。

アプリケーションをコンテナ化する利点

アプリケーションをコンテナ化すると、移植性、安定性、スケーラビリティ、セキュリティ、パフォーマンスなど、多くのメリットが得られます。アプリをDockerファイルでKinstaにデプロイすることで、カスタマイズ性も確保できます。

移植性

Dockerは、アプリケーションの実行に必要なものをすべてカプセル化するため、環境間で簡単に交換することができます。ローカルで実行する場合でも、異なるオペレーティングシステムを搭載したコンピュータで実行する場合でも、ステージング環境と本番環境で実行する場合でも、Dockerは同じコンポーネントでアプリケーションを構築するため、コーディング、テスト、デプロイが簡単です。

スケーラビリティ

Dockerでは、コンテナの複数のインスタンスを複数種類のサーバー上で実行できます。コンテナオーケストレータはさらに、アプリケーションのパフォーマンスに影響を与えることなく、トラフィックの増加に対応します。

安定性

隔離したコンテナでアプリを実行することで、開発、テスト、本番システム間でコードを移動する際に結果が予測可能になります。コンテナに必要なライブラリやパッケージの正確なバージョンが含まれ、依存関係のリビジョンが異なることによるバグのリスクを最小限に抑えることができます。

また、アプリを本番サーバーにデプロイする際には、Dockerは他のアプリケーションからの隔離を徹底するため、他のアプリケーションのトラフィック急増の影響も低減されます。

セキュリティ

Dockerコンテナは、従来のモデルよりも安全な環境を確保するのに有用です。アプリケーションを小さく、疎結合のコンポーネントに分割し、それぞれが互いに分離されるため、攻撃を受ける対象が大幅に減少します。Dockerコンテナでは、ハッカーによる悪用の機会が少なくなり、攻撃を受けても侵害が広がりにくい性質です。詳しくはDockerコンテナの9つのセキュリティベストプラクティスをご覧ください。

パフォーマンス

コンテナには、仮想マシンや従来のサーバーのようなオペレーティングシステム全体が含まれません。そのため、コンテナのフットプリントが小さくなり、構築と起動が高速になります。

カスタムデプロイメント

Kinstaでは、Buildpacks(ビルドパック)やNixpacksを使用してアプリケーションを自動でデプロイすることができます。しかし、ビルドプロセスがアプリのコードベースに基づき自動的にトリガーされる場合、カスタマイズの余地はあまりありません。Dockerfileを使用してKinstaにデプロイする場合には、アプリケーションのビルドとデプロイの方法を事細かに設定できます。

要件

Next.jsアプリケーションをDockerでデプロイするには、以下のものが必要になります。

Next.jsアプリケーションの利用を始める

既存のアプリケーションを利用する場合には、このステップは飛ばしてかまいません。そうでない場合には、新しいNext.jsアプリケーションの作成から始めましょう。

  1. ターミナルを開き、create-next-appをインストールします。
npm i -g create-next-app@latest
  1. インストールしたいディレクトリに移動し、新しいNext.jsアプリケーションをそのディレクトリに作成します。
npx create-next-app@latest new-app

Nextでは、アプリの設定オプションをいくつか指定することができます。今回の説明では、提案にあるデフォルトの設定をそのまま使用することにしましょう。

  1. 新しいアプリケーションをプレビューするには、new-appディレクトリに移動して次を実行します。
npm run dev

参考までに、この方法でサンプルアプリケーションを作成しました。

DockerファイルでNext.jsアプリをコンテナ化する

Next.jsアプリをコンテナ化してDockerでデプロイするには、アプリのルートディレクトリにDockerfileを作成します。

ビルドステージ

Dockerfileでは、まずアプリのbuildステージを作成して、アプリケーションをビルドします。

  1. buildステージのベースイメージとして、公式の最新安定版 Node.js alpineイメージを使用します。
FROM node:18-alpine AS build
WORKDIR /app
  1. package.jsonpackage-lock.jsonファイルをコンテナにコピーします。
COPY package*.json ./
  1. 以下でアプリの依存関係をインストールします。
RUN npm ci
  1. 以下で残りのアプリケーションコードをコンテナにコピーします。
COPY . .
  1. アプリケーションを次のようにビルドします。
RUN npm run build

ランタイムステージ

アプリケーションをデプロイするために、runtimeステージを作成します。

  1. runtimeステージのベースイメージとして、公式の最新安定版Node.js alpine イメージを使用します。
FROM node:18-alpine AS runtime
  1. 作業ディレクトリを/appに設定します。
WORKDIR /app
  1. package.jsonpackage-lock.jsonファイルをコンテナにコピーします。
COPY package*.json ./
  1. 本番環境の依存関係のみをインストールします。
RUN npm ci --only=production
  1. ビルドしたアプリをbuildステージからruntimeステージにコピーします。
COPY --from=build /app/.next ./.next
  1. publicフォルダをbuildステージからruntimeステージにコピーします。
COPY --from=build /app/public ./public
  1. ポート3000を公開します。
EXPOSE 3000
  1. コンテナを非特権ユーザーとして実行します。
USER node
  1. Next.jsアプリを起動します。
CMD ["npm", "start"]

以下のDockerfileができあがります。

FROM node:18-alpine AS build

WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:18-alpine AS runtime

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=build /app/.next ./.next
COPY --from=build /app/public ./public

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

Dockerでアプリをローカルにデプロイする

run npm devを使ってアプリケーションをプレビューすることもできますが、Dockerを使ってローカルで実行することで、本番環境を模倣し、アプリのDockerfileに加えた変更をテストしてプレビューすることができます。

アプリケーションをプレビューするには以下の操作を行います。

  1. docker buildでアプリをビルドします。
docker build -t next-docker .
  1. コンテナを実行してアプリをプレビューします。
docker run -p 3000:3000 next-docker
  1. ブラウザでhttp://localhost:3000を開きます。

コンテナ化したNext.jsアプリをKinstaにデプロイする

以下の手順に従って、Dockerfileを使用してアプリケーションをKinstaにデプロイします。

  1. アプリのコードベースをGitリポジトリ(GitHub、GitLab、またはBitbucket)にホスト
  2. MyKinstaアカウントにログインするか、新規アカウントを作成してアクセス
  3. サービスを追加」をクリックし、「アプリケーション」を選択
  4. Gitサービス、リポジトリ、デプロイ元のブランチを選択
  5. リポジトリにプッシュするたびにアプリをデプロイするには、「コミットに際し自動でデプロイ」 チェックボックスをクリックする
  6. 好みの(通常、利用者に近い)データセンターを選択し「続行」 をクリック
  7. ビルド環境を選択し、「Dockerfileを使用してコンテナイメージを設定」を選択
  8. Dockerfileがリポジトリのルートにない場合は「コンテキスト」でパスを指定し「続行」をクリック
  9. startコマンド」の項目は空欄のままで構いません(npm startを使用してアプリケーションの起動が実行されます)
  10. アプリケーションのポッドサイズとインスタンス数を選択し「続行」をクリック
  11. クレジットカード情報を入力し「アプリケーションの作成」をクリック

これでアプリケーションをデプロイする準備ができました。ステップ5で「コミットに際し自動でデプロイ」にチェックを入れている場合、システムにより自動でデプロイが実行されます。

まとめ

この記事では、従来のモデルと比較してDockerを使用する利点を扱い、Next.jsアプリのDockerfileを作成し、ローカルでDockerを使ってビルドし、Kinstaにデプロイする方法をご紹介しました。

この機会に、Kinstaのアプリケーションホスティングをお試しください。開発ワークフローを効率化するお手伝いをいたします。

37複数データセンターからの選択、GCPインフラストラクチャ、C2マシン、コンテナ環境、260+のPoP、Cloudflare統合を土台とした高性能CDN、エンタープライズレベルのファイアウォールDDoS保護、エッジキャッシュ、稼働状況監視(99%の稼働率保証)など、幅広い機能や性能をご用意。お客様のアプリの速度、安全性向上を後押しします。

Marcia Ramos Kinsta

Kinstaのエディトリアルチームリード。大のオープンソース&コーディング好き。IT業界向けのテクニカルライティングと編集に7年以上携わり、的確かつ簡潔なコンテンツを制作しながら、チームで協力し合い、ワークフローの改善を行っている。