AWS環境に自動デプロイというのを自分で1からやってみたくなったので、Capistrano
を使ってEC2にRailsアプリをデプロイしました。
「ググって出てきた簡単な使い方通りに進め、1通り手順とかイメージ掴めればいいかな〜」くらいの気持ちでやったのですが、エラーがかなり出て勉強になったので対応と合わせてまとめておきます。
基本的に参考にしたサイト
https://github.com/capistrano/capistrano
https://github.com/capistrano/rails
【Rails】 AWSのEC2にデプロイする方法~画像で丁寧に解説!
【Rails】 Capistranoを使ってデプロイを自動化しよう
あらかじめお伝え
-
エラーメッセージの深掘りができていない点が多々あります
※今回の私の目標は「Capistranoを使って自動デプロイの手順を1通り経験すること」であったため。 -
上記参考サイトに載っている手順は触れておりません
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)
$ 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のエージェント転送機能を使えるようにする
set :ssh_options, {
auth_methods: ['publickey'],
keys: ['~/.ssh/xxx.pem'],
forward_agent: true # これを追加
}
- ssh-addでgithubにssh接続する際の秘密鍵を追加
$ ssh-add ~/.ssh/xxx # github ssh接続の秘密鍵
参考
2. mainブランチとmasterブランチ
$ bundle exec cap production deploy
... not a valid object name: master
... tar アーカイブではないようです
masterが有効なオブジェクトではない、というメッセージでした。
GitHubではmaster
ではなくmain
ブランチになっているのが原因で、Capistranoではデフォルトでmaster
を探してしまうみたいです。
したがって、以下のように明示的にmain
を指定します。
# ブランチ指定
set :branch, 'main'
参考
これで解決しました。
3. OSの環境のエラー
$ 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
を直してねというメッセージでした。
$ bundle lock --add-platform x86_64-linux
上記で、修正されたGemfile.lock
をmain
にpushして解決です。
4. Credencialの設定がなくてエラー
$ 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内にコピーすることで解決しました。
参考
5. master keyが見つからずエラー
$ 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コワイ、、、)