Rubyと筋肉とギターとわたし

筋トレが仕事です

【Heroku】akhileshns/heroku-deploy@v3.12.12でRailsをデプロイするとerror:0308010C:digital envelope routines::unsupportedが発生する件について

どうもてぃ。

暖冬と言われていますが、一気にさむくなりましたね。体調には充分気をつけて残り少ない今年を乗り切りたいです。

今回は結構苦戦しました。

当方、Railsアプリケーション(not api mode)をGitHub Actionを用いてHerokuへ自動デプロイをしてます。が、先日突然nodejsのバージョン違いで発生するopensslのエラーがデプロイ時に出たので解決するに至りました。

現状出ている記事のどれを参考にしても解決できず、力技でなんとかしましたのでご参考に。

環境

  • Ruby 2.7.8 (alpine image)
  • Rails 6.0.6
  • nodejs v16.20.1

エラーログ

remote: -----> Installing node-v20.9.0-linux-x64        
remote: -----> Installing yarn-v1.22.19        
remote: -----> Detecting rake tasks        
remote: -----> Preparing app for Rails asset pipeline        
remote:        Running: rake assets:precompile        
remote:        /tmp/build_0eb98de1/vendor/ruby-2.7.8/lib/ruby/2.7.0/net/protocol.rb:66: warning: already initialized constant Net::ProtocRetryError        
remote:        /tmp/build_0eb98de1/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:68: warning: previous definition of ProtocRetryError was here        
remote:        /tmp/build_0eb98de1/vendor/ruby-2.7.8/lib/ruby/2.7.0/net/protocol.rb:206: warning: already initialized constant Net::BufferedIO::BUFSIZE        
remote:        /tmp/build_0eb98de1/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:214: warning: previous definition of BUFSIZE was here        
remote:        /tmp/build_0eb98de1/vendor/ruby-2.7.8/lib/ruby/2.7.0/net/protocol.rb:503: warning: already initialized constant Net::NetPrivate::Socket        
remote:        /tmp/build_0eb98de1/vendor/bundle/ruby/2.7.0/gems/net-protocol-0.2.1/lib/net/protocol.rb:541: warning: previous definition of Socket was here        
remote:        ** [NewRelic] FATAL : Config file at /tmp/build_0eb98de1/config/newrelic.yml doesn't include a 'staging' section!        
remote:        D, [2023-11-05T22:31:32.095473 #308] DEBUG -- sentry: Initializing the background worker with 2 threads        
remote:        D, [2023-11-05T22:31:32.095593 #308] DEBUG -- sentry: [Sessions] Sessions won't be captured without a valid release        
remote:        RAILS_ENV=staging environment is not defined in config/webpacker.yml, falling back to production environment        
remote:        yarn install v1.22.19        
remote:        [1/4] Resolving packages...        
remote:        [2/4] Fetching packages...        
remote:        [3/4] Linking dependencies...        
remote:        warning " > @babel/plugin-proposal-private-methods@7.18.6" has unmet peer dependency "@babel/core@^7.0.0-0".        
remote:        warning "@babel/plugin-proposal-private-methods > @babel/helper-create-class-features-plugin@7.22.15" has unmet peer dependency "@babel/core@^7.0.0".        
remote:        warning "@babel/plugin-proposal-private-methods > @babel/helper-create-class-features-plugin > @babel/helper-replace-supers@7.22.20" has unmet peer dependency "@babel/core@^7.0.0".        
remote:        warning " > @babel/plugin-proposal-private-property-in-object@7.21.11" has unmet peer dependency "@babel/core@^7.0.0-0".        
remote:        warning "@babel/plugin-proposal-private-property-in-object > @babel/plugin-syntax-private-property-in-object@7.14.5" has unmet peer dependency "@babel/core@^7.0.0-0".        
remote:        [4/4] Building fresh packages...        
remote:        Done in 14.64s.        
remote:        Compiling...        
remote:        Compilation failed:        
remote:        Error: error:0308010C:digital envelope routines::unsupported        
remote:            at new Hash (node:internal/crypto/hash:68:19)        
remote:            at Object.createHash (node:crypto:138:10)        
remote:            at CompressionPlugin.taskGenerator (/tmp/build_0eb98de1/node_modules/compression-webpack-plugin/dist/index.js:163:38)        
remote:            at taskGenerator.next (<anonymous>)        
remote:            at /tmp/build_0eb98de1/node_modules/compression-webpack-plugin/dist/index.js:216:49        
remote:            at CompressionPlugin.runTasks (/tmp/build_0eb98de1/node_modules/compression-webpack-plugin/dist/index.js:236:9)        
remote:            at /tmp/build_0eb98de1/node_modules/compression-webpack-plugin/dist/index.js:270:18        
remote:            at _next0 (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:37:17)        
remote:            at eval (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:53:1)        
remote:            at WebpackAssetsManifest.handleEmit (/tmp/build_0eb98de1/node_modules/webpack-assets-manifest/src/WebpackAssetsManifest.js:486:5)        
remote:            at AsyncSeriesHook.eval [as callAsync] (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:49:1)        
remote:            at AsyncSeriesHook.lazyCompileHook (/tmp/build_0eb98de1/node_modules/tapable/lib/Hook.js:154:20)        
remote:            at Compiler.emitAssets (/tmp/build_0eb98de1/node_modules/webpack/lib/Compiler.js:491:19)        
remote:            at onCompiled (/tmp/build_0eb98de1/node_modules/webpack/lib/Compiler.js:278:9)        
remote:            at /tmp/build_0eb98de1/node_modules/webpack/lib/Compiler.js:681:15        
remote:            at AsyncSeriesHook.eval [as callAsync] (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)        
remote:            at AsyncSeriesHook.lazyCompileHook (/tmp/build_0eb98de1/node_modules/tapable/lib/Hook.js:154:20)        
remote:            at /tmp/build_0eb98de1/node_modules/webpack/lib/Compiler.js:678:31        
remote:            at AsyncSeriesHook.eval [as callAsync] (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)        
remote:            at AsyncSeriesHook.lazyCompileHook (/tmp/build_0eb98de1/node_modules/tapable/lib/Hook.js:154:20)        
remote:            at /tmp/build_0eb98de1/node_modules/webpack/lib/Compilation.js:1423:35        
remote:            at AsyncSeriesHook.eval [as callAsync] (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:6:1)        
remote:            at AsyncSeriesHook.lazyCompileHook (/tmp/build_0eb98de1/node_modules/tapable/lib/Hook.js:154:20)        
remote:            at /tmp/build_0eb98de1/node_modules/webpack/lib/Compilation.js:1414:32        
remote:            at eval (eval at create (/tmp/build_0eb98de1/node_modules/tapable/lib/HookCodeFactory.js:33:10), <anonymous>:14:1)        
remote:            at process.processTicksAndRejections (node:internal/process/task_queues:95:5)        
remote:                
remote:         
remote:  !        
remote:  !     Precompiling assets failed.        
remote:  !        
remote:  !     Push rejected, failed to compile Ruby app.        
remote: 
remote:  !     Push failed        
remote: Verifying deploy...        

解決方法

  • GitHub Actionに NODE_OPTIONS=--openssl-legacy-provider を追加する
  • package.jsonでnode versionを固定する(engine指定)

↑2つの方法では解決できませんでした。今出てる解決方法はだいたいそれな気がする。

実際自分がやったのはHeroku側で NODE_OPTIONS=--openssl-legacy-provider を設定することでした。

  1. 該当アプリケーション選択
  2. Settingsへ
  3. Config VarsでReveal Config Varsを押す
  4. NOTE_OPTIONS, --openssl-legacy-provider を追加

これがアプリケーションコードを修正せずHeroku側の設定のみで解決できる方法です。

デプロイ検証するために毎度コードの設定をいじってGitHub ActionsをReRunする必要はありませんでした。

おわりに

おわり。