【Heroku】 error:0308010C が発生してデプロイに失敗する場合の解決策
Heroku Pipeline を使って運用しているRailsアプリケーションで、デプロイ時に以下のようなエラーが発生しました。
Error: error:0308010C:digital envelope routines::unsupported
発生したエラー
改めてエラーメッセージ全体を見てみます。
Compilation failed:
Error: error:0308010C:digital envelope routines::unsupported
at new Hash (node:internal/crypto/hash:68:19)
at Object.createHash (node:crypto:138:10)
at module.exports (/tmp/build_0e3c50c6/node_modules/webpack/lib/util/createHash.js:135:53)
at NormalModule._initBuildHash (/tmp/build_0e3c50c6/node_modules/webpack/lib/NormalModule.js:417:16)
at handleParseError (/tmp/build_0e3c50c6/node_modules/webpack/lib/NormalModule.js:471:10)
at /tmp/build_0e3c50c6/node_modules/webpack/lib/NormalModule.js:503:5
at /tmp/build_0e3c50c6/node_modules/webpack/lib/NormalModule.js:358:12
at /tmp/build_0e3c50c6/node_modules/loader-runner/lib/LoaderRunner.js:373:3
at iterateNormalLoaders (/tmp/build_0e3c50c6/node_modules/loader-runner/lib/LoaderRunner.js:214:10)
at iterateNormalLoaders (/tmp/build_0e3c50c6/node_modules/loader-runner/lib/LoaderRunner.js:221:10)
at /tmp/build_0e3c50c6/node_modules/loader-runner/lib/LoaderRunner.js:236:3
at context.callback (/tmp/build_0e3c50c6/node_modules/loader-runner/lib/LoaderRunner.js:111:13)
at /tmp/build_0e3c50c6/node_modules/babel-loader/lib/index.js:44:71 {
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'
}
Node.js v20.9.0
エラーメッセージにある error:0308010C
や ERR_OSSL_EVP_UNSUPPORTED
で検索すると、色々と情報が出てきます。
原因はOpenSSLの互換性
エラーはざっくり以下のような流れで発生していることがわかりました。
1. HerokuがデフォルトでNode.js 20.xをインストールするようになった
If a Node version isn’t specified in the engines section, Node.js 20.x is used automatically.
2. Node.js 17.x以降ではOpenSSL 3が使用されるが、Webpackがこれに対応してないため互換性エラーが出る
Node.js の OpenSSL の互換性については、以下の記事で解説されていました。
このRailsアプリケーションでは Gem Webpacker で Webpack を使用しているため、OpenSSL の互換性エラーに引っ掛かっていました。
解決策1 - 古いバージョンのOpenSSLを使用する
古い OpenSSL を使用する環境変数を設定することでエラーは解消しました。
Heroku 環境の Node.js でエラーが発生しているため、Heroku に環境変数を設定します。
heroku config:set NODE_OPTIONS='--openssl-legacy-provider' --app APP_NAME
ダッシュボードから環境変数を設定することも可能です。
解決策2 - HerokuのNode.jsをバージョンダウンする(非推奨)
もう1つ、Heroku にインストールされる Node.js を v20.x
から v16.x
にする方法があります。
こうすることで OpenSSL 3 が使用されなくなり、エラーは解消します。
手順は以下の通りです。
1. Node.js Buildpacksをインストール
インストールされているBuildpacksを確認
heroku buildpacks --app APP_NAME
heroku/nodejs
がなかった場合、以下2つのいずれかのコマンドを実行
# 他にBuildpacksが存在しなかった場合
heroku buildpacks:set heroku/nodejs --app APP_NAME
# 別のBuildpacksが既に存在した場合(heroku/ruby 等)
heroku buildpacks:add heroku/nodejs --app APP_NAME
補足:buildpacks:set
は単一、buildpacks:add
は複数のBuildpacksとして追加します[1](公式ドキュメントより)
2. package.jsonでインストールするNode.jsのバージョンを指定
package.json
に engines
セクションを追加します。
{
"name": "example-app",
"description": "a really cool app",
"version": "1.0.0",
+ "engines": {
+ "node": "16.x"
+ }
}
ただ、この方法はサポート期限切れの v16.x
を使用するため、推奨しません。
しかし私の場合は解決策2が必要でした。
というのも実は OpenSSL の互換性エラーとは別のエラーも同時に発生していました。これにより Heroku に環境変数を追加しても、反映されませんでした。
どうやら Heroku はエラーの発生するデプロイは反映せずにロールバックするという仕様みたいです。つまり、片方ずつエラーを解消してもダメということです。
そこで今回は少しややこしいですが、以下の手順でエラーを解決しました。
- 「Heroku の Node.js を
v16.x
に指定(解決策2)+ 別のエラー解決」の修正をデプロイ - 環境変数に
NODE_OPTIONS
を追加(解決策1) - Herokku の Node.js を
v20.x
に戻す
まとめ
今回は Heroku で error:0308010C
が発生してデプロイに失敗する場合の解決策についてまとめてみました。
私はかなり苦戦したので、同様のエラーで困っている方の助けになると幸いです。
参考サイト
以下のドキュメント、記事を参考にエラーの解決や記事の作成ができました。感謝申し上げます🙇♂️
Discussion