Node.js のデプロイのトラブルシューティング
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年05月15日(水)
Table of Contents
Node.js のデプロイが失敗した場合は、どのように調査したらよいでしょうか。ビルドの問題をトラブルシューティングするための次のステップを開始してください。
buildpack のチェック
そのアプリは、正式にサポートおよび保守されている buildpack を使用していますか。ほとんどの場合は、標準の buildpack が、単独または Heroku Ruby Buildpack などの他の buildpack とのペアのどちらであっても最適な選択肢です。
それを見つけるには、次を実行します。
$ heroku buildpacks
正式な buildpack を使用するには、次を実行します。
$ heroku buildpacks:set heroku/nodejs
Node と NPM のバージョンの比較
本番環境で、アプリの開発環境をできるだけ密接にミラーリングしたいと考えています。パッチのバージョンが多少ずれていても許容範囲内です。最初に、ローカルバージョンをチェックします。
$ node --version
$ npm --version
次に、その結果を package.json
内の engines
セクションと比較します。Node のバージョンが指定されていることを確認してください。
Heroku は、各デプロイでどのバイナリ (つまり、node
、npm
) が使用されているかをビルドログに出力します。
remote: -----> Installing binaries
remote: Resolving node version 20.x...
remote: Downloading and installing node 20.9.0...
remote: Using default npm version: 10.1.0
バイナリが同じローカルバージョンと一致しない場合は、package.json
で一致するバージョンを指定します。
ロックファイルが最新であることの確認
package-lock.json
や yarn.lock
などのロックファイルが存在し、アプリのリポジトリにチェックインされている場合は、そのファイルが最新であり、Git にチェックインされていることを確認してください。
package.json
でサードパーティの依存関係を参照する場合は、ロックファイルを使用することをお勧めします。
npm
package-lock.json
を更新するには、npm install
を実行し、変更を Git にチェックインします。
yarn
yarn.lock
ファイルを更新するには、yarn install
を実行し、変更を Git にチェックインします。
生成されたディレクトリがチェックインされない
アプリの node_modules
ディレクトリは、package.json
とロックファイルに一覧表示されている依存関係からビルド時に生成されます。node_modules
や、bower_components
などのその他の生成されたディレクトリはソース管理の対象外です。次のようにして確認します。
$ git ls-files | grep node_modules
結果が得られた場合は、node_modules
の追跡を停止するよう Git に指示します。
$ echo "node_modules" >> .gitignore
$ git rm -r --cached node_modules
$ git commit -am 'untracked node_modules'
開発環境と本番環境の違いのチェック
多くの Node アプリケーションは、NODE_ENV
環境変数の値に基づいて異なるロジックを実行するチェック機能を備えています。これらのチェックは、特に、たとえば Web アセットのビルド時や、開発中に画像を圧縮する場合に一般的です。
場合によっては、チェックが、デプロイしようとしたときにのみ現れる微妙なバグにつながることがあります。デプロイ中に新しいバグが現れた場合は、NODE_ENV
を production
に設定して、ローカルで再現できるかどうかを確認してください。
$ NODE_ENV=production npm start
.gitignore
のチェック
必要なファイルがローカルに存在していても、.gitignore
内の大まかすぎるルールにより、アプリの Git リポジトリへの取り込みが誤ってブロックされてしまう可能性があります。
例として、アプリケーションのルートにある lib
ディレクトリを除外するのが最適な場合がありますが、そのために次のように指定すると
lib/
Git は lib
という名前のすべてのサブディレクトリに再帰的に一致するため、ファイル js/library-name/lib/index.js
が Git リポジトリに含まれなくなります。この場合は、スラッシュを先頭に移動することによって解決します。これは、アプリケーションのルートディレクトリにある lib
ディレクトリにのみ一致します。
/lib
チケットを開く
これらのどの解決策も問題のアプリを解決するために機能しない場合は、Heroku でチケットを開いてサポートを受けてください。
一般的な問題
AWS プロキシのエラー
Node のダウンロード中にビルドがエラーで完了しない場合は、バイナリのダウンロードで問題が発生している可能性があります。ビルドのエラーは、次のように表示されることがあります。
-----> Installing binaries
engines.node (package.json): 10
engines.npm (package.json): unspecified (use default)
Resolving node version 10...
Error: Unknown error installing "10" of node
また、次のように表示されることもあります。
-----> Node.js app detected
curl: (35) OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to lang-common.s3.amazonaws.com:443
アプリのビルドで HTTP_PROXY
または HTTPS_PROXY
環境変数を設定すると、これらの種類のエラーが発生します。ビルドまたはアプリに HTTP_PROXY
または HTTPS_PROXY
環境変数が必要ない場合は、アプリの環境からこれらの変数を削除することをお勧めします。
$ heroku config:unset HTTP_PROXY HTTPS_PROXY
ビルド環境に HTTP または HTTPS 接続用のプロキシが必要な場合、プロセスを実行する前に NO_PROXY
環境変数を amazonaws.com
に設定します。環境設定を設定する別の方法を次に示します。
$ heroku config:set NO_PROXY=amazonaws.com
モジュールの欠落
package.json
に含まれているモジュールがビルドまたは本番アプリにない場合は、プルーニング中に Heroku によって削除された可能性があります。一般的なエラーは、次のように表示されます。
internal/modules/cjs/loader.js:960
throw err;
^
Error: Cannot find module 'express'
アプリの slug サイズを削減するために、buildpack はビルドの最後に package.json
から devDependencies
をプルーニングして、実行時に一覧表示される dependencies
のみが slug に含まれるようにします。プルーニングの実行後に必要な依存関係が devDependencies
に存在している場合は、その依存関係を dependencies
に移動して、buildpack によって削除されないようにします。
もう一つの解決策は、次の環境設定によって devDependencies
のプルーニングを完全にオフにすることです。
$ heroku config:set NPM_CONFIG_PRODUCTION=false
アプリで Yarn を使用する場合は、次のように実行します。
$ heroku config:set YARN_PRODUCTION=false
設定パッケージのインストールについての詳細は、Node.js サポートのドキュメントを参照してください。
正しくないポート設定
Heroku アプリは、アプリで設定されているどのポートにもバインドされません。アプリは Node process
を使用してポートにバインドします。
間違って設定すると、アプリは正常にデプロイされますが、繰り返しクラッシュします。ログに次のようなエラーが表示されることがあります。
heroku[router]: at=error code=H10 desc="App crashed" method=GET path="/" status=503 bytes= protocol=https
この問題を解決するには、process.env.PORT
変数を使用して Web サーバーをポートにバインドします。ローカル開発にポート 3000 を使用する場合、コードは次のようになります。
app.listen(process.env.PORT || 3000);
Node プロセスは、アプリで Heroku が設定する PORT
環境変数を受け取ります。
インストールおよびビルドスクリプトの失敗
依存関係のインストールまたはローカルでのビルドの実行が正常に完了したにもかかわらず、Heroku に移動するとビルドに失敗する場合があります。依存関係が Heroku でのみ失敗するという問題が発生した場合、One-off dyno を起動してスクリプトをデバッグすることをお勧めします。dyno は最新のデプロイの slug から作成されるため、Heroku 環境でデバッグするために、ビルドが成功するように試行してください。問題の依存関係をアンインストールするか、ビルドスクリプトを package.json
から削除するか、コードに別の変更を行うことで、ビルドを成功させることができます。
コードをステージングアプリにデプロイしたら、One-off dyno を作成します。
heroku run bash -a example-app
Running bash on ⬢ example-app... up, run.2524 (Basic)
$
dyno が起動したら、デバッグするスクリプトを確認して実行できます。必要に応じて依存関係をインストールします。
$ npm install debug
up to date, audited 52 packages in 2s
found 0 vulnerabilities
package.json
に cat
を実行すると、debug
がインストールされていることが確認できます。ビルドスクリプトが失敗することもありますが、その場合、verbose
フラグを指定して手動で実行できます。
$ npm run build-production --verbose