【Rails】（デプロイ初心者）Capistranoを使ってEC2に自動デプロイしたときに発生したエラーと対処法

AWS環境に自動デプロイというのを自分で１からやってみたくなったので、`Capistrano`を使ってEC2にRailsアプリをデプロイしました。
「ググって出てきた簡単な使い方通りに進め、１通り手順とかイメージ掴めればいいかな〜」くらいの気持ちでやったのですが、エラーがかなり出て勉強になったので対応と合わせてまとめておきます。

## 基本的に参考にしたサイト
https://github.com/capistrano/capistrano
https://github.com/capistrano/rails
[【Rails】 AWSのEC2にデプロイする方法~画像で丁寧に解説！](https://pikawaka.com/rails/ec2_deploy)
[【Rails】 Capistranoを使ってデプロイを自動化しよう](https://pikawaka.com/rails/capistrano)
## あらかじめお伝え

- エラーメッセージの深掘りができていない点が多々あります
※今回の私の目標は「Capistranoを使って自動デプロイの手順を１通り経験すること」であったため。

- 上記参考サイトに載っている手順は触れておりません
## Railsアプリの作成

今回はRails scaffoldでBookのCRUD操作ができるだけのアプリを用意しました。
#### 環境

- Ruby 3.1.2
- Rails 7.0.4.2
- M1 Mac

## AWSの環境のセットアップ

- VPC
- public subnet
- EC2
- セキュリティグループ
- Elastic IP
- ルーティングテーブル

このあたりを触って環境を作ります。

## デプロイ（ここからが本記事のメイン）
### 1. Permission denied (publickey)
```bash
$ bundle exec cap production deploy

.../.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/sshkit-1.21.3/lib/sshkit/runners/parallel.rb:15:in `rescue in block (2 levels) in execute': Exception while executing as ec2-user@xx.xx.xx.xx: git exit status: 128 (SSHKit::Runner::ExecuteError)
git stdout: Nothing written
git stderr: Permission denied (publickey).\r
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
```

`Cound not read from remote repository`なので、EC2がGitHubのソースコードを読むための権限がなく、弾かれてしまったようです。
これに対応するには、以下の対応をして解決しました。

- Capistranoの設定でsshのエージェント転送機能を使えるようにする
```ruby:deploy.rb
set :ssh_options, {
  auth_methods: ['publickey'],
  keys: ['~/.ssh/xxx.pem'],
  forward_agent: true # これを追加
}
```

- ssh-addでgithubにssh接続する際の秘密鍵を追加

```bash
$ ssh-add ~/.ssh/xxx # github ssh接続の秘密鍵
```

#### 参考
https://teratail.com/questions/241192

### 2. mainブランチとmasterブランチ

```bash
$ bundle exec cap production deploy

... not a valid object name: master
... tar アーカイブではないようです
```
masterが有効なオブジェクトではない、というメッセージでした。
GitHubでは`master`ではなく`main`ブランチになっているのが原因で、Capistranoではデフォルトで`master`を探してしまうみたいです。

したがって、以下のように明示的に`main`を指定します。

```ruby:deploy.rb
# ブランチ指定
set :branch, 'main'
```

#### 参考
https://qiita.com/9999Fringe/items/74313b8d9adf6de91967

これで解決しました。

### 3. OSの環境のエラー

```bash
$ bundle exec cap production deploy

Your bundle only supports platforms ["arm64-darwin-21"] but your local platform
is x86_64-linux. Add the current platform to the lockfile with
`bundle lock --add-platform x86_64-linux` and try again.
```

これはシンプルに対応しているOSの話ですね。EC2の`Amazon Linux`用に`Gemfile.lock`を直してねというメッセージでした。

```bash
$ bundle lock --add-platform x86_64-linux
```

上記で、修正された`Gemfile.lock`を`main`にpushして解決です。

### 4. Credencialの設定がなくてエラー

```bash
$ bundle exec cap production deploy

... Exception while executing as ec2-user@xx.xx.xx.xx: rake exit status: 1 (SSHKit::Runner::ExecuteError)
rake stdout: Nothing written
rake stderr: rake aborted!
ArgumentError: Missing `secret_key_base` for 'production' environment, set this string with `bin/rails credentials:edit` 
```

Credencialの設定がなく、エラーが発生しました。
下記参考のQiitaにだいたい書いてありますが、Production環境用に設定して、作成したkeyをEC2内にコピーすることで解決しました。

#### 参考

https://qiita.com/tatama/items/aaa1300f55da5da2933a

## 5. master keyが見つからずエラー

```bash
$ bundle exec cap production deploy

Missing encryption key to decrypt file with. Ask your team for your master key 
and write it to 
/var/www/capistrano-tutorial/releases/20230130121010/config/master.key
or put it in the ENV['RAILS_MASTER_KEY'].
```

master keyがなく、エラーが発生しました。
メッセージに従って、`~/.bushrc`に環境変数として設定したところ解決しました。

## 最後に
上記を経て、無事デプロイできました！
AWSにデプロイしたい、`Capistrano`使ってみたい、というところから始まって、とりあえず動くものができたのでよかったです。
デプロイに必要な最低限の作業がわかったのが収穫でした。
ちなみに、お金がかかる&何か良くない環境構築をしていたら怖いのでAWS環境は動作確認してすぐ消しました（AWSコワイ、、、）