Heroku の Node.js サポート
この記事の英語版に更新があります。ご覧の翻訳には含まれていない変更点があるかもしれません。
最終更新日 2024年05月15日(水)
Table of Contents
このドキュメントでは、Node.js アプリケーションの認識と実行に関連した Heroku の一般的な動作について説明します。アプリケーションのデプロイ方法についての詳細は、「Heroku スターターガイド (Node.js)」を参照してください。
アクティベーション
Heroku Node.js buildpack は、アプリケーションのルートディレクトリに package.json
ファイルがある場合に使用されます。
Node.js ランタイム
Node のバージョンは、GitHub によって一般に普及しているセマンティックバージョニング規約である Semver に準拠します。semver では MAJOR.MINOR.PATCH
形式のバージョンスキームが使用されます。
MAJOR
は互換性のない API 変更を示しますMINOR
は下位互換性のある方法で追加される機能を示しますPATCH
は下位互換性のあるバグ修正を示します
サポートされているランタイム
Heroku では、現在のバージョンの Node.js と、すべてのアクティブな長期サポート (LTS) バージョンがサポートされています。Heroku では、Node チームからの正式リリースの 24 時間以内に新規リリースがサポートされます。Node.js のリリーススケジュールに示されているように、Heroku では現在、Node.js バージョン 18.x
、20.x
、22.x
がサポートされています。
その他の使用可能なランタイム
Heroku は標準の Ubuntu Linux スタックに基づいているため、ほとんどの Node バージョン (>= 0.10.0
) をプラットフォームで実行できます。ただし、buildpack のテストとサポートは、アクティブ LTS リリースと Stable (安定) リリースを中心に行われます。
Node.js バージョンの指定
常に、開発やテストで使用しているランタイムに一致する Node.js バージョンを指定します。ローカルのバージョンを検索するには、次のようにします。
$ node --version
v20.9.0
最初に、アプリケーションで heroku/nodejs
buildpack を使用していることを確認します。
$ heroku buildpacks
=== issuetriage Buildpack URLs
1. heroku/nodejs
Heroku で使用する Node.js のバージョンを指定するには、package.json
の engines
セクションを使用します。v
を削除してバージョン番号のみを保存します。
{
"name": "example-app",
"description": "a really cool app",
"version": "1.0.0",
"engines": {
"node": "20.x"
}
}
Node バージョンが engines
セクションで指定されていない場合、Node.js 20.x
が自動的に使用されます。
Node から最新のパッチ更新を取得するために、パッチには x
を使用することをお勧めします。また、マイナー範囲 (20.9
など) または正確なバージョン (20.9.0
など) を指定することもできます。
Node では、サポートされているすべてのメジャーバージョンで定期的なセキュリティリリースが行われるため、20.x
のようにメジャー範囲を指定してセキュリティ更新を自動的に取得することをお勧めします。
パッケージマネージャーの指定
Node.js アプリケーションは npm、pnpm、Yarn を使用して構築できます。 各パッケージマネージャーを設定する手順については、以下を参照してください。
アプリケーションで使用するパッケージマネージャーは 1 つのみにしてください。
npm を使用する場合
Node.js は npm
にバンドルされているため、ほとんどの場合、npm バージョンを別途指定する必要はありません。ただし、異なるバージョンの npm
をローカルで意図的に使用する場合、Heroku で同じバージョンを指定できます。
{
"name": "example-app",
"description": "a really cool app",
"version": "0.0.1",
"engines": {
"npm": "10.x"
}
}
pnpm を使用する場合
アプリケーションのルートに package.json
と共に pnpm-lock.yaml
ファイルがある場合、Heroku では pnpm をダウンロードしてインストールし、これを使用して依存関係をインストールし、アプリケーションをビルドします。ローカルで使用するバージョンを指定して、Heroku で同じバージョンが使用されるようにします。
アプリケーションのビルドで pnpm のバージョンを指定するには、次のいずれかの方法を使用します。
package.json
のpackageManager
フィールドを使用する。{ "name": "example-app", "description": "a really cool app", "version": "1.0.0", "packageManager": "pnpm@9.0.5" }
This method uses Corepack which is preferred for pnpm tooling. The version declared in
package.json
must be exact but it can be configured from a version range with Corepack’s use command (e.g.;corepack use pnpm@9.x
).package.json
のengines.pnpm
フィールドを使用する。{ "name": "example-app", "description": "a really cool app", "version": "1.0.0", "engines": { "yarn": "9.0.5" } }
This method allows for version ranges like
9.0
or9.x
to be used. Ranges can be useful for keeping up to date with new releases but are not as safe as exact versions when it comes to reliable builds.
Yarn を使用する場合
アプリケーションのルートに package.json
と共に yarn.lock
ファイルがある場合、Heroku では Yarn をダウンロードしてインストールし、これを使用して依存関係をインストールし、アプリケーションをビルドします。ローカルで使用するバージョンを指定して、Heroku で同じバージョンが使用されるようにします。
アプリケーションのビルドで Yarn のバージョンを指定するには、次のいずれかの方法を使用します。
package.json
のpackageManager
フィールドを使用する。{ "name": "example-app", "description": "a really cool app", "version": "1.0.0", "packageManager": "yarn@4.1.1" }
This method uses Corepack which is preferred for Yarn tooling. The version declared in
package.json
must be exact but it can be configured from a version range with Corepack’s use command (e.g.;corepack use yarn@4.x
).package.json
のengines.yarn
フィールドを使用する。{ "name": "example-app", "description": "a really cool app", "version": "1.0.0", "engines": { "yarn": "4.1.1" } }
This method allows for version ranges like
4.1
or4.x
to be used. Ranges can be useful for keeping up to date with new releases but are not as safe as exact versions when it comes to reliable builds.
ビルド動作
Node.js アプリケーションは npm、pnpm、または Yarn を使用する場合、同じビルドプロセスをたどります。これらのビルド手順の詳細は次のとおりです。
パッケージのインストール
デフォルトでは、Heroku は package.json
の dependencies
および devDependencies
に定義されているすべての依存関係をインストールします。
インストールおよびビルドステップを実行した後、 Heroku はアプリケーションをデプロイする前に、devDependencies
に宣言されているパッケージを取り除きます。
Heroku では、ロックファイル (package-lock.json
、pnpm-lock.yaml
または yarn.lock
) を使用して、期待される依存関係ツリーをインストールします。これらのファイルを Git にチェックインして、環境全体の依存関係バージョンを同じにしてください。npm
を使用する場合、Heroku では npm ci
を使用してビルド環境を設定します。
npm install
の使用
ビルド環境を作成するために npm ci
ではなく npm install
を使用する場合、USE_NPM_INSTALL
環境変数を使用して buildpack に認識させることができます。次のように実行します。
$ heroku config:set USE_NPM_INSTALL=true
npm install
を使用する場合、Heroku キャッシュを使用してビルドを高速化する必要があります。npm install
を使用しない場合は、ビルドキャッシュを無効にします。
$ heroku config:set NODE_MODULES_CACHE=false
dependencies
のみのインストール
次の環境変数を設定することによって、dependencies
のみをインストールするよう Heroku に指示できます。
NPM_CONFIG_PRODUCTION=true
(npm の場合)YARN_PRODUCTION=true
(Yarn v1 の場合)
$ heroku config:set NPM_CONFIG_PRODUCTION=true YARN_PRODUCTION=true
プルーニングのスキップ
ビルドプロセスやターゲットとする環境によっては、devDependencies
で宣言されたパッケージを周辺に置いておく必要があるかもしれません。プルーニングステップは、ターゲット NODE_ENV
によって、あるいはこのステップをオプトアウトする環境変数 が設定されていれば、スキップできます。
すべてのパッケージマネージャで、NODE_ENV
が他の値である場合、プルーニングステップはスキップされます。
npm を使用し、プルーニングステップをスキップする
$ heroku config:set NPM_CONFIG_PRODUCTION=false
pnpm を使用し、プルーニングステップをスキップする
$ heroku config:set PNPM_SKIP_PRUNING=true
Yarn v1 を使用し、プルーニングステップをスキップする
$ heroku config:set YARN_PRODUCTION=false
Yarn v2 以上を使用し、プルーニングステップをスキップする
$ heroku config:set YARN2_SKIP_PRUNING=true
ビルドプロセスのカスタマイズ
デプロイ中に実行するビルドステップがアプリにある場合、package.json
で build
スクリプトを使用できます。
"scripts": {
"start": "node index.js",
"build": "webpack"
}
Heroku 用のカスタマイズが必要な build
スクリプトが package.json
にある場合、build
スクリプトの代わりに実行される heroku-postbuild
スクリプトを定義します。
"scripts": {
"start": "node index.js",
"build": "ng build",
"heroku-postbuild": "ng build --prod" // this will be run on Heroku
}
heroku-postbuild
スクリプトが指定された場合、build
スクリプトは実行されません。
Heroku 固有のビルドステップ
各パッケージマネージャーは標準の preinstall
および postinstall
スクリプトをサポートしていますが、Heroku の他のビルドステップの前または後のどちらかのみでスクリプトを実行することもできます。たとえば、Heroku が依存関係をインストールする前に npm
、git
、または ssh
を設定する場合や、依存関係がインストールされた後に本番アセットをビルドする場合です。
Heroku 固有のアクションの場合、heroku-prebuild
、heroku-postbuild
、および heroku-cleanup
スクリプトを使用します。
"scripts": {
"heroku-prebuild": "echo This runs before Heroku installs dependencies.",
"heroku-postbuild": "echo This runs after Heroku installs dependencies, but before Heroku prunes and caches dependencies.",
"heroku-cleanup": "echo This runs after Heroku prunes and caches dependencies."
}
環境変数
ビルド中にアプリの環境は使用可能なため、環境変数の値に基づいてビルド動作を調整できます。次に例を示します。
$ heroku config:set MY_CUSTOM_VALUE=foobar
ビルドフラグ
アプリでビルドステップを実行する場合は、開発および本番用に使用されるようにしてください。そうでない場合は、ビルドフラグ環境変数を使用して、ビルドスクリプトのフラグを設定します。たとえば、ビルドステップが以下であるとします。
"scripts": {
"build": "ng build"
}
NODE_BUILD_FLAGS
環境変数を設定できます。
$ heroku config:set NODE_BUILD_FLAGS="--prod"
この変数を設定すると、ビルドステップでは ng build --prod
を代わりに実行します。
NPM の設定
npm
は、NPM_CONFIG
で始まるあらゆる環境変数から設定を読み取ります。
また、プロジェクトのルートの .npmrc
ファイル経由で npm
の動作を制御することもできます。
NPM_CONFIG_PRODUCTION が true の場合、npm は NODE_ENV が ‘production’ であるサブシェル内のすべてのスクリプトを自動実行します。
プライベート依存関係
NPM Enterprise や Gemfury などのプライベート依存関係ソースからプルする場合、プロジェクトはアクセストークンを使用して代替レジストリを設定する必要があります。
プライベートレジストリ URL を .npmrc
に追加します。この場合、パブリックであっても NPM のレジストリを指定して、プライベート用に使用されるスコープでこのスコープを置き換えます。次に、認証トークンを使用してポイントするレジストリ URL を追加します。
echo "@scope:registry=https://registry.npmjs.org" >> .npmrc
echo -e "//registry.npmjs.org/:_authToken=\${NPM_TOKEN}" >> .npmrc
このレジストリ URL は npm レジストリに固有ですが、他のプライベートパッケージレジストリと同様の URL になる可能性があります。プライベートレジストリのドキュメントを確認してください。
.npmrc
は次のようになります。
@scope:registry=https://registry.npmjs.org
//registry.npmjs.org/:_authToken=${NPM_TOKEN}
NPM_TOKEN
が Heroku 設定に追加され、ビルドでトークンにアクセスしてプライベートパッケージをインストールできることを確認します。
heroku config:set NPM_TOKEN=PRIVATE_NPM_TOKEN
バイナリダウンロードのカスタマイズ
環境変数 NODE_BINARY_URL
および YARN_BINARY_URL
をカスタム URL に設定することで、Node と yarn のバイナリのダウンロード先をカスタマイズできます。次に例を示します。
$ heroku config:set NODE_BINARY_URL=https://s3.amazonaws.com/your-custom-binary-url/
キャッシュの動作
Heroku では、ビルドをまたいで持続するビルドキャッシュを維持します。このキャッシュには npm、Yarn、bower のキャッシュが保存されます。
必要に応じて、Node.js アプリのすべてのキャッシュを無効化できます。
$ heroku config:set NODE_MODULES_CACHE=false
$ git commit -am 'disable node_modules cache' --allow-empty
$ git push heroku main
カスタムキャッシュ
Heroku はデフォルトで、node_modules
および bower_components
ディレクトリを保存します。トップレベルの package.json に cacheDirectories
配列を指定することで、これらのデフォルトをオーバーライドできます。
たとえば、クライアントおよびサーバーのサブディレクトリ内でビルドする場合は、次のようになります。
"cacheDirectories": ["client/node_modules", "server/node_modules"]
また、アプリで何らかの種類の大きいディレクトリが必要で、data/dictionary.txt に保管される場合は、次のようになります。
"cacheDirectories": ["data"]
ランタイムの動作
buildpack では、node
、npm
、node_modules/.bin
を PATH
に設定して、heroku run で実行したり Procfile 内で直接使用したりできるようにします。
$ cat Procfile
web: npm start
NODE_ENV
環境変数はデフォルトで “production” に設定されますが、任意の文字列に設定できます。
$ heroku config:set NODE_ENV=staging
通常、NODE_ENV は “production” にします。express
を含むいくつかのモジュールでは、NODE_ENVに基づいてそれらの動作を暗黙的に変更します。
デフォルトの Web プロセスタイプ
最初に、Heroku はプロセスタイプを指定する Procfile を検索します。
ビルドプロセス中にアプリのルートディレクトリに Procfile
が存在しない場合、package.json
で指定できるスクリプトである npm start
を実行して Web プロセスを開始します。次に例を示します。
"scripts": {
"start": "node server.js"
}
アプリの構成で web
以外のプロセスのみを実行する場合、web
を明示的にスケールダウンし、他のプロセスタイプをスケールアップします。たとえば、次のようになります。
$ heroku scale web=0 worker=1
警告
ビルドに失敗した場合、Node.js buildpack は Node アプリケーション内の一般的な問題を特定し、警告と共にベストプラクティスとなる推奨事項を提供します。
また、Node.js の一般的な問題のトラブルシューティングに役立つドキュメントもあります。
アドオン
デフォルトでプロビジョニングされるアドオンはありません。アプリ用のデータベースが必要な場合は、明示的に追加してください。
$ heroku addons:create heroku-postgresql
複数の buildpack による動作
Node.js buildpack を他の buildpack と一緒に使用すると、後続の buildpack で使用する node
、npm
、node_modules
の各バイナリが PATH
に自動的にエクスポートされます。
理解を深める
Heroku Node.js buildpack はオープンソースです。buildpack の動作方法を技術的にさらに理解するには、github.com/heroku/heroku-buildpack-nodejs のソースコードを調べてください。