【ITニュース解説】How to Deploy a Next.js App on a VPS the Production Way
2026年10月20日に「Dev.to」が公開したITニュース「How to Deploy a Next.js App on a VPS the Production Way」について初心者にもわかりやすく解説しています。
ITニュース概要
Next.jsアプリをVPSに本番環境で安定稼働させるためのデプロイ手順と、見落としがちなノウハウを解説。適切なNode.js導入、ビルド時の注意点、PM2によるプロセス管理、NginxとSSL設定、トラブルシューティングまで、長期運用を見据えた実用的な方法を詳しく説明している。
ITニュース解説
Next.jsで作成したウェブアプリケーションを、VPS(仮想プライベートサーバー)と呼ばれる自分専用のサーバーで安定して動かすための具体的な手順と、本番環境で運用する際に特に注意すべき点について解説する。単にアプリを動かすだけでなく、長期間にわたって問題なく稼働させるための「生産性のあるデプロイ」を実現する方法が中心である。
まず、サーバーに適切なNode.jsのバージョンを導入することが最初のステップである。Next.js 16のようなモダンなバージョンは、Node 20.9以降を必要とし、Node 22 LTS(長期サポート版)が推奨されている。しかし、UbuntuなどのOSが提供する標準パッケージ管理システム(apt)からは、古いNode.jsしか手に入らないことが多い。そのため、NodeSourceという専門のリポジトリから最新のNode.jsをインストールする必要がある。具体的なコマンドはcurl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -に続き、sudo apt install -y nodejsを実行することになる。
また、サーバー環境によってはNODE_ENV=productionという環境変数が自動的に設定されている場合がある。この状態でnpm installを実行すると、開発時にのみ必要なパッケージ(devDependencies)がインストールされず、ビルドが失敗することがある。これを避けるためには、開発用パッケージも明示的に含めるnpm install --include=devを使うか、あるいはサーバーでの利用により適したnpm ciコマンドを使うことが望ましい。npm ciは、package-lock.jsonファイルに記録されている正確なバージョンのパッケージのみをインストールするため、開発環境とサーバー環境での依存関係のずれを防ぐのに役立つ。
次に、アプリケーションのビルドプロセスに移る。これはデプロイの中でも特に問題が発生しやすい部分である。正しい手順は、まずgit pullで最新のコードを取得し、次にnpm ciで依存関係をインストールし、最後にnpm run buildでアプリケーションをビルドすることである。ここで非常に重要なのが、npm run buildが完全に終了し、.next/BUILD_IDというファイルが生成されていることを確認してから次の作業に進むことである。ビルド中にプロセスマネージャーを再起動してしまうと、不完全なビルドがデプロイされ、古いバージョンのアプリが動き続けたり、奇妙なエラーが発生したりすることがある。ビルドが成功したかどうかを必ず確認する習慣が、多くのデプロイの失敗を防ぐ。
ビルドに関するもう一つの重要な注意点として、Next.jsアプリケーションでは、NEXT_PUBLIC_というプレフィックスが付いた環境変数は、ビルド時にJavaScriptバンドルの中に直接組み込まれるという特性がある。つまり、これらの変数の値を変更した場合、アプリケーションを再起動するだけでは新しい値は反映されず、必ず再ビルドが必要となる。一方、プレフィックスのないサーバーサイドの環境変数は、再起動するだけで変更が反映される。この違いを理解しておかないと、「新しいAPIキーが反映されない」といった問題に直面することがある。
さらに、next buildコマンドは実行時にかなりのメモリを消費する。メモリが1GBしかないVPSのような環境では、ビルド中にメモリ不足(OOM: Out Of Memory)によってプロセスが強制終了されてしまうことがある。この場合も不完全なビルドが残り、古いバージョンのサイトが稼働し続けるため、問題に気づきにくい。これを避けるためには、最低でも2GB以上のメモリを持つVPSを使うか、メモリが足りない場合は2GB程度のスワップファイルを追加して仮想メモリを確保する対策が必要である。
アプリケーションを常に稼働させ続けるためには、PM2のようなプロセスマネージャーの利用が必須である。SSHセッションを通じてnpm run startを実行しても、SSHセッションが閉じるとアプリケーションも停止してしまう。PM2をグローバルにインストールし、pm2 start npm --name "myapp" -- startというコマンドでNext.jsアプリケーションを起動する。pm2 saveコマンドで現在のプロセス設定を保存しておくと、次にサーバーが再起動したときにPM2が自動的にアプリケーションを立ち上げてくれるようになる。pm2 startupコマンドを実行して表示される指示に従うことで、システム起動時にPM2自身が自動起動するように設定できる。
もし複数のNext.jsアプリケーションを同じVPSで動かす場合は、それぞれ異なるポート番号で起動する必要がある。デフォルトのポートは3000だが、例えば2つ目のアプリはpm2 start npm --name "app2" -- start -- -p 3001のように別のポートを指定する。デプロイ更新の際は、git pull && npm ci && npm run build && pm2 restart myappという一連のコマンドを実行することになるが、ここでも「ビルド完了を待ってから再起動する」という原則を守ることが重要である。ビルドと再起動を同じコマンドチェーンに含めず、ビルドが完全に成功してから再起動するべきである。
次に、Nginxをリバースプロキシとして導入し、CertbotでSSL証明書を設定する。アプリケーションが直接動作するポート3000をインターネットに公開するのはセキュリティ上のリスクがあるため避けるべきである。Nginxはウェブサーバーとして、パブリックなポート80(HTTP)と443(HTTPS)で外部からのアクセスを受け付け、それを内部のNext.jsアプリケーションが稼働するポート3000に転送する役割を担う。
Nginxの設定ファイルは比較的シンプルだが、特にヘッダー情報の設定が重要である。proxy_set_header X-Forwarded-Proto $scheme;という行を含めないと、Next.jsはHTTPSでアクセスされてもHTTPとして認識してしまい、リダイレクトループが発生したり、生成されるURLが正しくなかったりといった問題を引き起こすことがある。
SSL/TLS証明書の設定は、Certbotを使うことで非常に簡単に行える。sudo apt install -y certbot python3-certbot-nginxでCertbotをインストールし、sudo certbot --nginx -d yourdomain.comを実行するだけで、Nginxの設定が自動的に書き換えられ、SSL証明書がインストールされる。Certbotは証明書の自動更新設定も行ってくれるので、期限切れの心配も少ない。sudo certbot renew --dry-runで更新テストを行い、問題なく更新できることを確認しておくことが推奨される。
最後に、ファイアウォールの設定を忘れてはならない。外部からアクセスが必要なSSH(ポート22)、HTTP(ポート80)、HTTPS(ポート443)以外のポートは閉じ、特にポート3000はアプリケーションがNginx経由でしかアクセスできないようにブロックする。これはサーバーセキュリティの基本中の基本である。
アプリケーションが稼働し始めてから発生しやすい問題とその対処法も理解しておくべきである。
Nginxから502エラーが表示された場合、これはNginx自体の問題ではなく、Nginxの背後で動作しているNext.jsアプリケーションが停止していることを意味する。Nginxを再起動しても解決しないため、まずpm2 logsコマンドでアプリケーションのログを確認し、次にNginxのエラーログをチェックして原因を特定する必要がある。
public/ディレクトリに新しい画像ファイルなどを追加した場合、デプロイ後にこれらのファイルが提供されないことがある。これは、Next.jsサーバーが起動時にビルドマニフェストをキャッシュしているためであり、pm2 restart myappでアプリケーションを再起動することで解決する。
ビルドが途中で失敗し、不完全な.nextディレクトリが残ってしまった場合、古いバージョンのサイトが引き続き表示されるため、問題に気づきにくい。ビルドの終了コードとBUILD_IDの確認を徹底することで、この問題を回避できる。
ISR(Incremental Static Regeneration)のようなキャッシュ機能を使用すると、アプリケーションのメモリ使用量が時間とともに増加する傾向がある。pm2 monitなどのツールを使ってメモリ使用量を監視し、必要に応じて対策を講じることが重要である。
また、環境変数に関するセキュリティ意識も必要である。NEXT_PUBLIC_プレフィックスが付いていない環境変数は、ブラウザに公開されるべきではない。これらの秘密情報は.gitignoreに追加し、ソースコードリポジトリに含めないようにする。
VPSにNext.jsアプリケーションをデプロイすることは、マネージドプラットフォームに比べて手間がかかるが、月額6ドルから22ドル程度の費用で、データベースやリバースプロキシを含めてすべてを自分の管理下に置けるという大きな利点がある。初期設定に数時間かかるものの、その後の運用でログやサーバーのシェルに直接アクセスし、問題発生時には自分で詳細を調査し、解決できる自由度が得られる。一時的なデモ目的であればマネージドサービスの方が手軽だが、1年以上運用するような本格的なアプリケーションでは、VPSでのセルフホスティングがコストと運用の柔軟性の両面で有利である。上記で述べたNode.jsの準備、確実なビルド、PM2によるプロセス管理、NginxとSSLの設定、そしてファイアウォールといった基本的な手順を押さえることが、安定した本番運用への鍵となる。それ以外の多くは、問題発生時のデバッグ作業に集約される。