AWS

AWS CodePipelineでRuby on RailsアプリケーションをEC2に自動デプロイ

・シンプルなRailsアプリケーションをCodePipeline経由でEC2に自動デプロイする方法の紹介
・デプロイに必要なファイルの設定も紹介

ローカルで作成したRailsアプリケーションをEC2で動かしたい場合、ソースコードをEC2に送ってrails serverコマンドで立ち上げる方法が一般的かなと思います。

今回はCodePipelineを利用して、ソースコードをプッシュした後にEC2にデプロイしてrails serverコマンドを実行する一連の流れを自動化する方法もあります。

Railsアプリケーションについて

Railsアプリケーションはrails newコマンドで作成したプロジェクトの状態です。

バージョンは下記となります。
Ruby:2.6.3
Rails:5.2.1

CodePipelineおよび関連サービスについて

CodePipeline、 CodeCommit、CodeDeployの設定については下記を参照ください。

デプロイ設定ファイル(appspec.yml)

デプロイ時の設定ファイルには、CodeDeployのライフサイクルに沿ったイベントをappspec.ymlに設定します。

ライフサイクル

appspec.yml の中身は下記となります。

version: 0.0
os: linux
files:
  - source: /
    destination: /var/www/rails_hello
permissions:
   - object: /var/www/
     pattern: "**"
     owner: ec2-user
     mode: 775
hooks:
  ApplicationStop:
    - location: scripts/stop_server
      timeout: 300
      runas: root
  BeforeInstall:
    - location: scripts/clean
      timeout: 300
      runas: root
  ApplicationStart:
    - location: scripts/start_server
      timeout: 300
      runas: root

files項目でプッシュされたソースコードをEC2に移動します。
hooks項目にライフサイクルイベントを記載して処理ファイルを記載します。

デプロイ設定ファイル(ApplicationStop scripts/stop_server)

デプロイで最初に起動されます。
ここではrails serverを停止させるコマンドを実行しています。

#!/bin/bash
sudo kill -KILL -s QUIT `cat /var/www/rails_hello/tmp/pids/server.pid`

デプロイ設定ファイル(BeforeInstall scripts/clean)

ライフサイクル上だと3番目に実行されます。
今回は ApplicationStop の次に実行されます。

ここではCodeCommitにプッシュしたプロジェクトの一貫性保持のためEC2にあるプロジェクトを削除します。

#!/bin/bash
sudo rm -rf /var/www/rails_hello

デプロイ設定ファイル(ApplicationStart scripts/clean)

今回は BeforeInstall の次に実行します。

rails server実行前の準備としてbundle installやマイグレーションを行い最後にrails serverコマンドを実行します。

CodeDeployの実行ユーザがrootのためec2-userで実行するようにしていたり、Dockerfile同様に毎コマンド単位にチェンジディレクトリコマンドを行っています。

また、rails serverコマンドはクライアント側でも確認出来るように「 -b 0.0.0.0 」オプションを入れており
CodeDeploy側でエラーとならないよう「-d」オプションでバックグラウンド実行してStdoutを返すようにしています。

#!/bin/bash
su -l ec2-user -c 'cd /var/www/rails_hello && bundle install'
su -l ec2-user -c 'cd /var/www/rails_hello && bundle exec rake db:migrate'
su -l ec2-user -c 'cd /var/www/rails_hello && bundle exec rails s -d -b 0.0.0.0 -p 3000'

難しく省略した箇所

最初はEC2の環境構築(RubyやRailsインストール)も行う予定でしたが、CodeDeployの実行ユーザがrootから変わらずどうやってもエラーとなっているため環境構築はEC2内で行いました。
ここはECSへのデプロイでリベンジですね。

また、ApplicationStopも、rails serverが実行していることが前提の作りとなっています。
ここも別サイト様を見るとNginxやUnicornでやっているためそもそもrails serverで行うことが良くないのかなと考えています。

テストも行っていないのでここも今後の課題ですね。

最後に

以上でRailsアプリケーションをCodePipelineを使ってEC2にデプロイする方法の紹介となります。

確認すべきところが一杯あり中々難しかったです。
1回構築すれば便利ですがそこに至るまでの時間と機会を考えないとモチベーションを保つのが難しいですね。

Ruby on Rails学習の片手間で考えていると私は半分諦めかけました・・・

参考したサイト様は以下となります。

https://developers.fukurou-labo.co.jp/ci-cd%E5%AE%9F%E8%A3%85%E7%B7%A8/
https://developers.fukurou-labo.co.jp/ci-cd%E5%AE%9F%E8%A3%85%E7%B7%A8/

https://dev.classmethod.jp/articles/codedeploy-ruby-on-rails/