EC2インスタンスが初期化or再構築された際に、発生する
Railsアプリをデプロイする際、EBは/opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh
を呼び出しbundle install
を実行する。
この際、Bundlerのバージョンがデフォルトは1.16.0という古いものになっており(何で?)、最近のバージョンのRailsでは互換性がなくエラーが発生する。
ERROR: [Instance: i-###############] Command failed on instance. Return code: 1 Output: (TRUNCATED)...:infind_spec_for_exe': can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException) from /opt/rubies/ruby-2.5.5/lib/ruby/site_ruby/2.5.0/rubygems.rb:308:in activate_bin_path'
from /opt/rubies/ruby-2.5.5/bin/bundle:23:in'. Hook /opt/elasticbeanstalk/hooks/appdeploy/pre/10_bundle_install.sh failed. For more detail, check /var/log/eb-activity.log using console or EB CLI. INFO: Command execution completed on all instances. Summary: [Successful: 0, Failed: 1].`
解決するには対応するバージョンのBundlerをインストールすればいい。
これまではeb ssh
でgem install bundler -v 2.0.2
を叩いてからデプロイしていた。
しかしインスタンスがAuto Scalingに設定されていると、何度でもEC2が再構築されてしまい、予期せぬときにこのエラーが発生しサーバーダウンしてしまう。
なので、デプロイ時の10_bundle_install.sh
が実行される前に、自動でBundlerをインストールしてもらうシェルスクリプトを作成する。
注意点は、10より先の09以下の番号をファイル名の先頭に付けること。シェルスクリプトはアルファベット順に実行される。
09_gem_install_bundler
files:
"/opt/elasticbeanstalk/hooks/appdeploy/pre/09_reinstall_bundler.sh" :
mode: "000775"
owner: root
group: root
content: |
#! /bin/bash
EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir)
EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir)
. $EB_SCRIPT_DIR/use-app-ruby.sh
cd $EB_APP_STAGING_DIR
echo "Installing compatible bundler"
gem install bundler -v 2.0.2