本記事は、開発環境のCloud9からAWSサービスを連携してデプロイすることをゴールにした連載記事です。
Railsアプリをデプロイしよう!!の全体目次はこちらをご覧ください。
本編では、前編に続き、Cloud9から本番環境へデプロイするための設定を進めていきます。
目次
事前準備
S3へバケット作成
新たにバケットを作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-92-1024x534.png)
下記にて作成しました。
バケット名:dc-app-bucket
AWS リージョン:東京
このバケットのブロックパブリックアクセス設定:パブリックアクセスをすべて ブロック
デフォルトの暗号化:有効→Amazon S3 キー (SSE-S3)
ロール作成①
CodeDeployからEC2にアクセスためのロールを作成
ロールを作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-93-1024x535.png)
AWSサービス > CodeDeployを選択します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-94-1024x566.png)
ユースケースの選択でCodeDeployを選択します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-95-1024x559.png)
ロールの作成では、特に指定せずに次に進みます。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-96-1024x555.png)
タグの追加は任意です。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-97-1024x552.png)
ロール名を指定して作成完了です。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-98-1024x565.png)
ポリシー作成
IAM > ポリシーを選択して、ポリシーを作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-99-1024x532.png)
[JSON]タブに以下を貼り付けて次に進みます。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:Get*",
"s3:List*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-100-1024x556.png)
ポリシーの名前は任意の名前をつけて、作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-101-1024x562.png)
ロール作成②
追加でロールを作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-102-1024x541.png)
AWSサービス > EC2を選択します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-103-1024x572.png)
先ほど作成したポリシーをアタッチします。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-104-1024x551.png)
タグ名はそのままスキップして、最後にロール名を入力して作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-105-1024x558.png)
続いて、EC2で該当のインスタンスに対してIAMロールを変更します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-106-1024x535.png)
先ほど作成したロールをアタッチします。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-107-1024x529.png)
本番環境にCodeDeployAgentをインストール・起動
AWS CodeDeploy を使用するには、事前にCodeDeployエージェントのインストールが必要です。
下記コマンドをそれぞれ実行します
ターミナル(ssh)
$ sudo yum update
$ sudo yum install ruby
$ sudo yum install wget
$ cd /home/ec2-user
# このURLは東京リージョンのCodeDeployリソースキットファイルが置いてある場所です
$ wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install
$ chmod +x ./install
$ sudo ./install auto
そして下記コマンドで実行中か確認できればOKです。
ターミナル(ssh)
$ sudo service codedeploy-agent status
=>The AWS CodeDeploy agent is running as PID 22231
AppSpec file作成
appspec.ymlをアプリケーションソースコードのルートに作成し、デプロイの定義を書いてきます。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-113-1024x561.png)
中身は適宜変更してください。
version: 0.0 # 0.0固定
os: linux # デプロイ先サーバーのOS
files: # アプリケーションの配置場所
- source: /
destination: /var/www/rails/DC_product
permissions: # 配置ディレクトリのパーミッション
- object: /var/www/rails/DC_product
owner: ec2-user #{ユーザー名}
group: ec2-user #{ユーザーグループ名}
pattern: "**"
mode: 775
type:
- file
- directory
hooks: # デプロイのライフサイクルイベント
ApplicationStop:
- location: deployment_scripts/stop_application.sh
runas: root #{シェルスクリプトの実行ユーザー名}
BeforeInstall:
- location: deployment_scripts/remove_old_files.sh
runas: root #{シェルスクリプトの実行ユーザー名}
AfterInstall:
- location: deployment_scripts/make_sockets_directory.sh
runas: root #{シェルスクリプトの実行ユーザー名}
- location: deployment_scripts/install_gems.sh
runas: root #{シェルスクリプトの実行ユーザー名}
- location: deployment_scripts/run_db_migrations.sh
runas: root #{シェルスクリプトの実行ユーザー名}
- location: deployment_scripts/compile_assets.sh
runas: root #{シェルスクリプトの実行ユーザー名}
ApplicationStart:
- location: deployment_scripts/start_application.sh
runas: root #{シェルスクリプトの実行ユーザー名}
デプロイライフサイクルイベントの作成
appspec.ymlに記載したデプロイのライフサイクルイベントを設定します
アプリケーションルートにdeployment_scriptsディレクトリを作成し、
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-114-1024x554.png)
各スクリプトを新規ファイルとして作成します。
stop_application.sh
remove_old_files.sh
make_sockets_directory.sh
install_gems.sh
run_db_migrations.sh
compile_assets.sh
start_application.sh
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-115-1024x547.png)
下記のスクリプトを参考にしてみてください。
# Unicornの動作状況を確認し、起動していれば停止させる。
if [ -e /var/www/rails/DC_product/tmp/pids/unicorn.pid ]; then
sudo kill -QUIT `cat /var/www/rails/DC_product/tmp/pids/unicorn.pid`
fi
sudo rm -rf /var/www/rails/DC_product
sudo mkdir /var/www/rails/DC_product
sudo mkdir -p /var/www/rails/DC_product/run/sockets
sudo chown -R ec2-user /var/www/rails/DC_product
su -l ec2-user -c 'cd /var/www/rails/DC_product && bundle install'
su -l ec2-user -c 'cd /var/www/rails/DC_product && bundle exec rake db:migrate RAILS_ENV=production'
sudo touch /var/www/rails/DC_product/yarn-error.log
sudo chown -R ec2-user /var/www/rails/DC_product/yarn-error.log
sudo mkdir /var/www/rails/DC_product/node_modules
sudo chown -R ec2-user /var/www/rails/DC_product/node_modules
sudo mkdir /var/www/rails/DC_product/tmp
sudo chown -R ec2-user /var/www/rails/DC_product/tmp
sudo mkdir /var/www/rails/DC_product/public/
sudo chown -R ec2-user /var/www/rails/DC_product/public/
npm install -g node-sass
su -l ec2-user -c 'cd /var/www/rails/DC_product && RAILS_ENV=production bundle exec rake assets:precompile'
#nginxの再起動
sudo systemctl restart nginx
#unicornの起動
su -l ec2-user -c 'cd /var/www/rails/DC_product && bundle exec unicorn_rails -c /var/www/rails/DC_product/config/unicorn.conf.rb -E production -D'
開発環境へgem ‘unicorn’追加
gem ‘unicorn’をインストールします。
group :production do
gem 'unicorn'
end
config以下にunicorn.conf.rbを新規作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-125-1024x557.png)
unicorn.conf.rbは下記を参考にしてください。
$worker = 2
$timeout = 30
$app_dir = "/var/www/rails/DC_product" #自分のアプリケーション名
$listen = File.expand_path 'run/sockets/unicorn.sock', $app_dir
$pid = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
$std_log = File.expand_path 'log/unicorn.log', $app_dir
# set config
worker_processes $worker
working_directory $app_dir
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen $listen
pid $pid
# loading booster
preload_app true
# before starting processes
before_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
old_pid = "#{server.config[:pid]}.oldbin"
if old_pid != server.pid
begin
Process.kill "QUIT", File.read(old_pid).to_i
rescue Errno::ENOENT, Errno::ESRCH
end
end
end
# after finishing processes
after_fork do |server, worker|
defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end
開発環境のdatabase.ymlを編集
database.ymlをRDS用に書き換えます。
#production以下をRDS用に書き換え
production:
<<: *default
# RDS MySQL用
database: <%= Rails.application.credentials.database[:database_rds] %>
username: <%= Rails.application.credentials.database[:username_rds] %>
password: <%= Rails.application.credentials.database[:password_rds] %>
host: <%= Rails.application.credentials.database[:host_rds] %>
そして、credentials.yml.encへ環境変数を追加しておきます。
ターミナル(cloud9)
$ EDITOR="vi" bin/rails credentials:edit
i で編集モードにして
database:
database_rds: dc_production #データベースの名前
username_rds: root #RDSで設定したユーザー名
password_rds: ***** #RDSで設定したパスワード
host_rds: dc********.ap-northeast-1.rds.amazonaws.com #RDSのエンドポイント
esc で編集終了後、:wq で上書き保存します。
CodeDeploy
デプロイのアプリケーションを作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-108-1024x539.png)
アプリケーション名を指定し、コンピューティングプラットフォームでEC2/オンプレミスを選択して作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-110-1024x534.png)
続いて、デプロイグループの作成をします。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-111-1024x534.png)
下記にて設定して作成します。
デプロイグループ名の入力:DC-production-Deployment-Group
サービスロール:先ほど作成したロールを指定
デプロイタイプ:インプレース
環境設定:Amazon EC2 インスタンス(デプロイ先のEC2のキーとタグを指定します)
デプロイ設定:CodeDeployDefault.OneAtATime
Load balancer:「ロードバランシングを有効にする」のチェックを外す
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-112.png)
CodePipeline
続いてCodePipelineの設定を進めていきます。
まず、パイプラインを作成します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-116-1024x526.png)
下記にて設定します。
高度な設定 > アーティファクトストアにてカスタムロケーションを指定して、バケットを今回作成したapp-bucketを指定します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-117-1024x826.png)
続いて、ソースステージを追加します。
下記にて設定します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-118-1024x654.png)
ビルドステージは、今回作成していないのでスキップします。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-120-1024x537.png)
続いて、デプロイステージを追加します。
赤枠の箇所をそれぞれ指定します。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-121-1024x619.png)
最後に確認画面をチェックして、作成完了です。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-122-930x1024.png)
これでmasterブランチにpushすると自動でデプロイが実行されます。
試しにmasterブランチにpushすると、自動でCodePipelineが実行されました。
Sourceは成功、Deployは失敗でした。
![](https://senrenseyo.com/wp-content/uploads/2021/08/image-123-1024x536.png)
Deployに関しては、筆者は40回程繰り返して、エラー解消しつつ成功しました。
今回紹介しているコードを使用すれば、もっと少ない回数で成功できると思います。
本編は以上です。お疲れ様でした。