Elastic Beanstalkで、Rails(PostgreSQL)アプリケーションをデプロイしよう！

## はじめに

- Elastic Beanstalk CLIのインストール
- データベースのセットアップ
- 環境の作成〜デプロイまで

などは[こちら](https://qiita.com/yuyasat/items/4d93b4ad4f86a6e13d50)に詳しく書かれてますので割愛します。
以下、詰まった点をまとめます。

**環境**

- Ruby 2.6.5
- Rails 5.2.3
- bundler 2.0.2

## 詰まった所① リージョンの設定
Elastic Benastalkの管理画面のリージョンがなぜか「シンガポール」になっており、
`eb create`しても全く反映されず、何度も作り直すハメに。。
超基本的な事ですが、ここが「**東京**」(指定したリージョン)になっているか確認しましょう。
<img width="341" alt="スクリーンショット 2019-10-30 13.26.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286816/399909d4-314c-ae10-68cf-be602688ae0b.png">


## 詰まった所② マスターキーの設定

忘れがちなのが、Rails5.2から導入されたマスターキーの設定です。
自身のプロジェクト内の`master.key`からキーをコピーして、
`eb setenv`コマンドでRAILS_MASTER_KEYを設定できます。
もしくは、管理画面の[設定]→[環境プロパティ]欄から、下記のように設定できます。

<img width="843" alt="スクリーンショット 2019-10-30 13.56.18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286816/a4b417ec-1aac-89f9-e5cf-ffa2191bf14e.png">
 
## 詰まった所③ データベースの設定

環境変数の設定が少しややこしいので補足します。

データベースを作成し、`config/database.yml`を作成した後、
環境変数を設定する必要があります。
[こちら](https://qiita.com/yuyasat/items/4d93b4ad4f86a6e13d50)では、`eb setenv`コマンドを使用していましが、マスターキーの設定と同様、管理画面からも設定できます。

各環境変数は、管理画面の[設定]→[データベース]から参照できます。
<img width="777" alt="スクリーンショット 2019-10-30 14.13.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286816/8e0a67e2-aff5-336d-9513-a1832f186290.png">


参照した値を[設定]→[環境プロパティ]から設定してください。
<img width="877" alt="スクリーンショット 2019-10-29 19.20.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/286816/0a1c323e-a3a1-7d56-9b1b-e6adda4836f8.png">

## 詰まった所④ assets:precompileの途中でエラーが起きてしまう。

```
rake aborted!
ExecJS::RuntimeError:
(execjs):1
/opt/rubies/ruby-2.6.5/bin/bundle:23:in `load'
/opt/rubies/ruby-2.6.5/bin/bundle:23:in `<main>'
Tasks: TOP => assets:precompile
(See full trace by running task with --trace).
Incorrect application version "app-7f9e-191030_161041-stage-191030_161041" (deployment 3). Expected version "app-7f9e-191030_154017" (deployment 2).
100 % of CPU is in use.
```

こんなエラーが出ました。
CPUが100%使われているのが原因のようです。
環境によりますが、管理画面の[設定]→[環境プロパティ]で、t2.micro　=>　t2.mediumに変更して解決しました。(t2.smallでもいけた。)

## 詰まった所⑤ アセットパイプライン
アセットパイプラインが正しく使えておらず、フォントが表示されませんでした。
Herokuではなぜか表示できていたのですが、Beanstalkでは「正確に」設定する必要があるようです！

[Rails Asset Pipelineがうまくいかないときの問題の切り分けかた](https://qiita.com/metheglin/items/c5c756246b7afbd34ae2)を参考にさせていただきmした

私の場合、**CSSのurl()などで指定するリンク指定**が間違っていました
- css形式は使えないので、scssに変更
- scss内の`url` => `asset_url`に変更

を行い、無事プリコンパイルされたフォントを読み込むことができました！

## 詰まった所⑥ Bundlerのバージョンが合ってないと怒られる

Bundlerのバージョンが合ってない〜、
bundler —-version 2.0.２をinstallして！と怒られます。
[こちら](https://stackoverflow.com/questions/55360450/elastic-beanstalk-cant-find-gem-bundler-0-a-with-executable-bundle-gem)を参考に、bundlerの`.ebextensions`ディレクトリを作成してconfigファイルを作成してください。

```.ebextensions/10_container_commands.config
files:
  # Runs before `./10_bundle_install.sh`:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/09_gem_install_bundler.sh" :
    mode: "000775"
    owner: root
    group: users
    content: |
      #!/usr/bin/env 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)
      # Source the application's ruby, i.e. 2.6. Otherwise it will be 2.3, which will give this error: `bundler requires Ruby version >= 2.3.0` 
      . $EB_SCRIPT_DIR/use-app-ruby.sh

      cd $EB_APP_STAGING_DIR
      echo "Installing compatible bundler"
      gem install bundler -v 2.0.2
      gem update --system
```
このconfigファイルで`bundle_install`が行われる前に、`gem install bundler -v 2.0.2`が行われ、
無事bundlerがインストールできました。。

(追記)アセットパイプラインを正しく、設定し直してデプロイし直したら、エラーが出なくなりました。
原因が分かりません。。誰か詳しい方教えてください(>_<)
## 役に立つコマンドオプション

ステージングした段階で、デプロイして試したい！

```
$ eb deploy --staged
```

コマンドがタイムアウトするまでの時間を延長したい！(タイムアウトが早いため)

```
$ eb deploy --timeout 30 # タイムアウトまで30分になる
```

詳しくは、[公式ドキュメント](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb3-cmd-commands.html)を参考に。

## 最後に

とても便利なPaaSではありますが、

- デプロイにとても時間がかかる(20分以上くらい)
- 設定変更の反映にも時間がかかる
- Herokuよりも設定画面が分かりにくい

がデメリットかなと感じました。

次は、こちらを試してデプロイを高速化してみようと思います。

- [事前にprecompileしたassetsをS3に配置してdeployを高速化する方法](http://hakutoitoi.hatenablog.com/entry/2013/03/06/013753)


そして何よりインフラ知識が無いに等しいので、中で何が行われてるのか基礎から勉強しないとですね！

## 参考

以下の記事を参考にさせていただきました。ありがとうございました。

- [Deploying a Rails 5.2 PostgreSQL app on AWS Elastic Beanstalk](https://evrim.io/deploying-a-rails-52-postgresql-app-on-aws-elastic-beanstalk/)
- [Ruby on Railsの環境構築をElastic Beanstalkで行う](https://qiita.com/yuyasat/items/4d93b4ad4f86a6e13d50)
- [Elastic Beanstalk: can't find gem bundler (>= 0.a) with executable bundle (Gem::GemNotFoundException)](https://stackoverflow.com/questions/55360450/elastic-beanstalk-cant-find-gem-bundler-0-a-with-executable-bundle-gem)
- [事前にprecompileしたassetsをS3に配置してdeployを高速化する方法](http://hakutoitoi.hatenablog.com/entry/2013/03/06/013753)