初心者向け! Rails6+CircleCI+Capistrano+AWS(EC2)で自動デプロイ
#はじめに
先日、ポートフォリオ作成後、AWSにCapistranoとCircleCIを使ってCIツールによる自動デプロイを実装できたので、備忘録として残しておこうと思います。
なお、前述したとおり備忘録としてなので参考になる保証はありません。
#前提
・Railsアプリが作成できていること
・EC2にCapistranoで自動デプロイを実現できていること
以上の条件に当てはまる場合にのみCIツールによるCapistranoの自動デプロイを行います。
#開発環境
##ローカル
・Rails6
・MySQL5.6.50
・Docker
・docker-compose
##本番
・EC2
・RDS(MariaDB)
・Unicorn
・Nginx
・Capistrano
本願環境にはDockerとdocker-composeは用いていません。
#手順
①CircleCIにEC2にログインするための秘密鍵を設定する
②.circleci/config.ymlにssh接続の記述をし、ログインできるか確かめる
③githubのmasterブランチにmergeもしくはpushしたときにCapistranoによるデプロイを行う
#1)CircleCIにEC2ログインの秘密鍵を設定する
多くの人はここで詰まる事が多く、筆者自身も2時間くらいつまりました。
まず、どの鍵が必要なのかがわからないということでつまります。
必要なのは、ssh
からEC2へログインする時に使うキーペア
と呼ばれる鍵です。
インスタンスを作成する時にpemファイル
形式でダウンロードする秘密鍵をCircleCIにも登録します。
ここで1つ注意点があり、CircleCIで使えるのはpem形式のみ
ということです。
OPENSSH
形式の場合はpem形式
にする必要があるので下記の記事を参考に実行してみてください。(筆者の場合は最初からpem形式だったため、この辺は詳しくないので。。。)
ということなので、ターミナルのssh
ディレクトリに移って、以下のコマンドを実行します。
.ssh % cat XXXXXXXXXXXXX.pem
# ご自身のEC2にログインする際のキーペア
すると以下のように非常に長い暗号が出力されます。
-----BEGIN RSA PRIVATE KEY-----
WWIEXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
# まだまだありますが割愛
-----END RSA PRIVATE KEY-----%
これを-----BEGIN RSA PRIVATE KEY-----
から-----END RSA PRIVATE KEY-----%
までコピーします。
もしくは以下のような方法で一括コピーも可能です。
.ssh % pbcopy < ~/.ssh/XXXXXXXXX.pem
このコマンドを使うことで先ほどの長い暗号をコピーすることができます。
1-2)CircleCIにキーペア登録
CircleCIのprojectに移り、project settingにを開きます。(右上の歯車アイコンをクリック)
すると以下のように設定画面に遷移するので、メニューバーのSSH Keys
を選択して、鍵を設定します。
ページが切り替わったら、スクロールして以下のAdd SSH Key
をクリックしましょう。
クリックすると以下のようになるので、Hostname
とPrivate Key
を入力して、Add SSH Key
をクリックします。
Hostname
にはElasticIP
を入れてもいいですが、筆者の場合は独自ドメインを取得していたためwww.myapp.com
のような形で記入しました。
続いてPrivate Key
には、先ほどコピーした暗号を貼り付けます。
しばらくすると、元の画面に戻ると思います。すると、Fingerprint
なる項目に数字と文字と「:」の文字列が存在していると思います。それをコピーしてメモなどに保存しておきましょう。
また、以下のようにDeploy Key
とUser Key
を設定しておきましょう。
これの設定をしないと、CircleCiのCode Check
の段階でGit
を認証せずにエラーになるため、必ず設定しましょう。
CircleCI(GUI)での設定は以上です。
#2).Circlci/cofig.ymlの記述
次にCircleCIでSSH接続できるか確認します。
以下のように存在している記述のsteps:
- checkout
の下などに記述を加えます。
筆者の場合はCapistranoの前はHerokuとCIパイプラインを構築してたため記述を加え、git push
しました。
- add_ssh_keys:
fingerprints: "XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"
この記述を加え確認しましょう。
以下のように成功していたらOKです。
#3)githubのmasterブランチにmergeもしくはpushしたときにCapistranoによるデプロイを行う
ここからが実際に、CIツールによるCapistrano自動デプロイの実装です。
まずこちらが成功したコードです。
version: 2.1
orbs:
ruby: circleci/ruby@1.1.0
jobs:
build:
docker:
- image: circleci/ruby:2.6.5-node-browsers
environment:
BUNDLER_VERSION: 2.1.4
steps:
- checkout
- run: gem install bundler -v 2.1.4
- run:
name: Which bundler?
command: bundle -v
- ruby/install-deps
deploy:
docker:
- image: circleci/ruby:2.6.5-node-browsers
environment:
BUNDLER_VERSION: 2.1.4
steps:
- checkout
- ruby/install-deps
- add_ssh_keys:
fingerprints: "XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"
- deploy:
name: Capistrano deploy
command: bundle exec cap production deploy
workflows:
version: 2.1
build-deploy:
jobs:
- build
- deploy:
requires:
- build
filters:
branches:
only: master
筆者が参考にしたのは参考文献にもある記事と公式ですが、難しかったです(笑)
1つずつ解説すると、dockerのimageは自分のrubyのバージョンに合わせ、bundlerの自分のバージョンに合わせるような記述をしました。
まずjob
としてコードチェックのためのbuild
を行い、bundlerのインストールするようにします。
そしてdeploy job
ではCapistranoを走らせるようにして、どのSSHに接続するかを指定しています。
これが先ほど設定したり、記述したadd_ssh_keys:
という記述に当たります。
その下のコマンドで実際にCapistranoが走るという構図になっています。
そしてworkflows
ではonly: master
としてmasterブランチにpushもしくはmergeがあった場合に行うように設定しています。
詳しい説明は下記の記事や、記事内で参考にしていた文献に書いてありますので、そちらの方も合わせて読むとより理解しやすいと思います。
結構、苦労しましたが、なんとか実装できました。
皆さんも頑張ってください。
#参考文献
Discussion