Ruby 2.7 → 3.2 への Elastic Beanstalk 推奨プラットフォーム載せ替え時にハマったこと一覧

## Elastic Beanstalk のプラットフォーム入れ替え
Ruby 2.7 から 3.2 へのアップデートを行なった。
ローカルで動作が担保されていざデプロイ！のフェーズでインフラ(Elastic Beanstalk)にてつまづいたことを残しておく。

:::note
(旧)
Ruby 2.7 running on 64bit Amazon Linux 2/3.4.7

(新)
Ruby 3.2 running on 64bit Amazon Linux 2023/4.0.10
:::


アプリケーションでハマったことは↓にて記載

https://qiita.com/lyd-ryotaro/items/2e7d3eeb1adaff9f7848

## 前提
Amazon Linux2 から Amazon Linux 2023 に最新のプラットフォームは変更になっている。
おそらくこのせいで今までの初期セットアップではうまく行かない場面が多々あった。（コンテナに載せ替えた方が早かったんじゃないかと思うがそれはまたの機会に行う。）

## ハマったこと一覧
### nodeインストール時にエラーが起きる
`.ebextensions` で行っていた `node` と `yarn` のインストールでエラーが起きる
```terminal:cfn-init.log
01_node_get (sudo curl -sL https://rpm.nodesource.com/setup_15.x | bash -) failed 2024-08-06 06:39:00,399
[ERROR] Error encountered during build of prebuild_2: Command 01_node_get failed Traceback (most recent call last): File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 579, in run_config CloudFormationCarpenter(config, self._auth_config, self.strict_mode).build(worklog) File "/usr/lib/python3.9/site-packages/cfnbootstrap/construction.py", line 277, in build changes['commands'] = CommandTool().apply( File "/usr/lib/python3.9/site-packages/cfnbootstrap/command_tool.py", line 127, in apply raise ToolError(u"Command %s failed" % name) cfnbootstrap.construction_errors.ToolError: Command 01_node_get failed 2024-08-06 06:39:00,402
```

#### 解決策
インストールしようとしている`node`がそもそも古い
新しいバージョンをインストールさせるかと思ったが、`node`と`yarn`はデフォルトでインストール済みだったのでわざわざインストールのし直しは不要と考え削除。

### amazon-linux-extras install epel が使えずに ffmpegthumbnailer がインストールできない
Amazon Linux2 では使えていたが Amazon Linux2023 では使えない
`ffmpeg`ライブラリのインストールに使っていたができない。

- AL2の書き方
```install-ffmpeg.config
commands:
  01_enable_epel_repository:
    command: |
      amazon-linux-extras install epel -y
  02_enable_rpmfusion_repository:
    command: |
      sudo yum install --nogpgcheck -y https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-7.noarch.rpm https://mirrors.rpmfusion.org/nonfree/el/rpmfusion-nonfree-release-7.noarch.rpm || true
  03_install_dependencies:
    command: |
      wget https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/l/libass-0.13.4-6.el7.x86_64.rpm
      sudo rpm -ivh libass-0.13.4-6.el7.x86_64.rpm
      wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libva-1.8.3-1.el7.x86_64.rpm
      sudo rpm -ivh libva-1.8.3-1.el7.x86_64.rpm
      sudo yum install -y ffmpeg ffmpeg-devel ffmpegthumbnailer
```

> Extra Packages for Enterprise Linux (EPEL) は、エンタープライズレベルの Linux オペレーティングシステム用の多数のパッケージを作成することを目的とした Fedora コミュニティ内のプロジェクトです。このプロジェクトは主に、RHEL および CentOS パッケージを作成してきました。AL2 は CentOS 7 との互換性が高いのが特徴です。そのため、多くの EPEL7 パッケージが AL2 で動作します。しかし、AL2023 は EPEL または EPEL のようなリポジトリをサポートしていません。
※参照元
https://docs.aws.amazon.com/ja_jp/linux/al2023/ug/compare-with-al2.html#epel


#### 解決策
ここ大変だったので別記事に詳しく書きました。

https://qiita.com/lyd-ryotaro/items/c527ac14ab7e60aff0cc

### bundle install 時にスペースが足りない
```terminal
2024/08/06 07:38:31.741584 [ERROR] An error occurred during execution of command [app-deploy] - [stage ruby application]. Stop running the command. Error: install dependencies in Gemfile failed with error Command bundle config set --local deployment true failed with error exit status 31. Stderr:There was an error while trying to write to `/var/app/staging/.bundle/config`.
There was insufficient space remaining on the device.
```

デフォルトで自動生成されるEBSのサイズが確かに今までのより小さい
[![Image from Gyazo](https://i.gyazo.com/cc792cd3feac3dc2fc837c527bab60ca.png)](https://gyazo.com/cc792cd3feac3dc2fc837c527bab60ca)

#### 解決策
`.ebextensions` でボリュームサイズを指定することで解決
```ebs-storage.config
option_settings:
  aws:autoscaling:launchconfiguration:
    RootVolumeType: gp2
    RootVolumeSize: "40"
```

`.ebextensions`じゃなくてもEBのコンソールから設定しても解決するかもしれない。
[![Image from Gyazo](https://i.gyazo.com/c8b95a01015c2a93117e83ca3d053fcd.png)](https://gyazo.com/c8b95a01015c2a93117e83ca3d053fcd)

### pumaが立ち上がっては死んでを繰り返す

#### irb について
```terminal:/var/log/puma/puma.log
[21676] ! Unable to start worker
[21676] cannot load such file -- irb
[21676] <internal:/usr/share/ruby3.2-rubygems/rubygems/core_ext/kernel_require.rb>:37:in `require'
    <internal:/usr/share/ruby3.2-rubygems/rubygems/core_ext/kernel_require.rb>:37:in `require'
 (~略~) 
[21676] Early termination of worker
```

調査 `/var/app/current` で `bundle exec rails s` してみる
```terminal
$ sudo su
$ bundle install
$ bundle exec rails s
```

`irb` がないとのこと
```terminal
<internal:/usr/share/ruby3.2-rubygems/rubygems/core_ext/kernel_require.rb>:37:in `require': cannot load such file -- irb (LoadError)
Did you mean?  erb
               drb
```

#### 解決策
下記リンクを参考に `irb` の `gem` を入れてみると解決

https://github.com/rails/rails/issues/42373

Gemfileに追加
```config:Gemfile
gem 'irb', '~> 1.4'
```

#### rexml がないとのこと
```terminal
[191289] ! Unable to start worker
[191289] cannot load such file -- rexml/document
[191289] <internal:/usr/share/ruby3.2-rubygems/rubygems/core_ext/kernel_require.rb>:37:in require'
    <internal:/usr/share/ruby3.2-rubygems/rubygems/core_ext/kernel_require.rb>:37:in require'
```

#### 解決策
Gemfileに追加
```config:Gemfile
gem 'rexml', '~> 3.2', '>= 3.2.4'
```

### libsassにて No such file or directory. (LoadError) エラーが起きる
```terminal
Could not open library '/var/app/current/vendor/bundle/ruby/3.2.0/gems/sassc-2.4.0/ext/libsass.so': /var/app/current/vendor/bundle/ruby/3.2.0/gems/sassc-2.4.0/ext/libsass.so: cannot open shared object file: No such file or directory. (LoadError) Searched in <system library path>
```

#### 解決策
`sassc` のバージョンを下げる
```config:Gemfile
gem "sassc", "< 2.2.0"
```

下記リンク参照

https://stackoverflow.com/questions/77496256/elasticbeanstalk-ruby-3-2-2-platform-sassc-loaderror

https://github.com/sass/sassc-ruby/issues/146

### assets:precompile で error:0308010C が発生
```terminal
Error: error:0308010C:digital envelope routines::unsupported
```
AL2023になったことでNodeバージョンが上がったことが原因の模様
下記を参考にして　Elastic Beanstalk の 環境変数に下記を設定
`NODE_OPTIONS` `--openssl-legacy-provider`

https://stackoverflow.com/questions/69692842/error-message-error0308010cdigital-envelope-routinesunsupported

しかしEBの環境変数に設定しただけじゃ解消しなかった。
SSHして下記は成功することを確認。EBのコンソールから設定した環境変数をうまく読んでくれない？
```terminal
$ bundle exec rails assets:precompile NODE_OPTIONS=--openssl-legacy-provider
```

#### 解決策

`RAILS_SKIP_ASSET_COMPILATION`を`true`にし、EBによる自動の`precompile`はOFFにする。

その上で
`.platform > hooks > predeploy > 01_manual_precompile.sh` を用意し、`NODE_OPTIONS`をつけて自前で`compile`実行

```shell:01_manual_precompile.sh
#!/bin/bash
cd /var/app/staging;
bundle exec rails assets:precompile NODE_OPTIONS=--openssl-legacy-provider
```

下記Issueも参考になる

https://github.com/vuejs/vue-cli/issues/6770#issuecomment-1778416417

### additional_path が null で compile に失敗
```terminal
NoMethodError: undefined method `+' for nil:NilClass (NoMethodError)
fetch(:additional_paths) + resolved_paths
```

#### 解決策
webpacker.yml に `additional_paths: []` を追加
```yaml:webpacker.yml
default: &default
  source_path: app/javascript
  source_entry_path: packs
  additional_paths: [] #追加
```



## まとめ Tips
ローカルでは動作するのにインスタンスで起きる調査ってなかなかしんどい。
こういうエラーはSSHしてからコマンドを実際に打ってみてどんなエラーが発生しているのかを特定するのが大事。
エラーで検索すると大体先人が記録を残してくれる（感謝）。

```terminal:例 サーバーが立ち上がらない時
$ cd /var/app/current
$ sudo su
$ bundle exec rails s
```