Node.js のデプロイのトラブルシューティング
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2022年11月28日(月)
Table of Contents
Node.js のデプロイが失敗した場合は、どのように調査したらよいでしょうか。ビルドの問題をトラブルシューティングするための次の簡単なステップを開始してください。
buildpack のチェック
そのアプリは、正式にサポートおよび保守されている buildpack を使用していますか。ほとんどの場合は、標準の buildpack が、単独または他の buildpack (Heroku Ruby 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 12.x...
remote: Downloading and installing node 12.16.3...
remote: Using default npm version: 6.14.4
これらのバイナリは、同じローカルバージョンに一致している必要があります。そうでない場合は、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 アセットのビルド時、開発中に JavaScript の縮小や画像の圧縮のオーバーヘッドを回避するために一般的です。
場合によっては、これが、デプロイしようとしたときにのみ現れる微妙なバグにつながることがあります。デプロイ中に新しいバグが現れた場合は、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
に設定します。これを行うには、Node プロセスを実行する前に環境にこれを設定する (つまり、export 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
に移動して、それが削除されないようにします。
もう一つの解決策は、devDependencies
のプルーニングを完全にオフにすることです。これを行うには、npm の場合は次を設定します。
$ 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 $APP_NAME
Running bash on ⬢ app-name... up, run.2524 (Basic)
$
dyno が起動したら、デバッグするスクリプトを確認して実行できます。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