本記事は、開発環境のCloud9からAWSサービスを連携してデプロイすることをゴールにした連載記事です。
Railsアプリをデプロイしよう!!の全体目次はこちらをご覧ください。
本編では、前編に続き、Cloud9から本番環境へデプロイするための設定を進めていきます。
目次
事前準備
S3へバケット作成
新たにバケットを作成します。
下記にて作成しました。
バケット名:dc-app-bucket
AWS リージョン:東京
このバケットのブロックパブリックアクセス設定:パブリックアクセスをすべて ブロック
デフォルトの暗号化:有効→Amazon S3 キー (SSE-S3)
ロール作成①
CodeDeployからEC2にアクセスためのロールを作成
ロールを作成します。
AWSサービス > CodeDeployを選択します。
ユースケースの選択でCodeDeployを選択します。
ロールの作成では、特に指定せずに次に進みます。
タグの追加は任意です。
ロール名を指定して作成完了です。
ポリシー作成
IAM > ポリシーを選択して、ポリシーを作成します。
[JSON]タブに以下を貼り付けて次に進みます。
{
"Version": "2012-10-17",
"Statement": [
{
"Action": [
"s3:Get*",
"s3:List*"
],
"Effect": "Allow",
"Resource": "*"
}
]
}
ポリシーの名前は任意の名前をつけて、作成します。
ロール作成②
追加でロールを作成します。
AWSサービス > EC2を選択します。
先ほど作成したポリシーをアタッチします。
タグ名はそのままスキップして、最後にロール名を入力して作成します。
続いて、EC2で該当のインスタンスに対してIAMロールを変更します。
先ほど作成したロールをアタッチします。
本番環境にCodeDeployAgentをインストール・起動
AWS CodeDeploy を使用するには、事前にCodeDeployエージェントのインストールが必要です。
下記コマンドをそれぞれ実行します
$ 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です。
$ sudo service codedeploy-agent status
=>The AWS CodeDeploy agent is running as PID 22231
AppSpec file作成
appspec.ymlをアプリケーションソースコードのルートに作成し、デプロイの定義を書いてきます。
中身は適宜変更してください。
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ディレクトリを作成し、
各スクリプトを新規ファイルとして作成します。
stop_application.sh
remove_old_files.sh
make_sockets_directory.sh
install_gems.sh
run_db_migrations.sh
compile_assets.sh
start_application.sh
下記のスクリプトを参考にしてみてください。
# 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を新規作成します。
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へ環境変数を追加しておきます。
$ 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
デプロイのアプリケーションを作成します。
アプリケーション名を指定し、コンピューティングプラットフォームでEC2/オンプレミスを選択して作成します。
続いて、デプロイグループの作成をします。
下記にて設定して作成します。
デプロイグループ名の入力:DC-production-Deployment-Group
サービスロール:先ほど作成したロールを指定
デプロイタイプ:インプレース
環境設定:Amazon EC2 インスタンス(デプロイ先のEC2のキーとタグを指定します)
デプロイ設定:CodeDeployDefault.OneAtATime
Load balancer:「ロードバランシングを有効にする」のチェックを外す
CodePipeline
続いてCodePipelineの設定を進めていきます。
まず、パイプラインを作成します。
下記にて設定します。
高度な設定 > アーティファクトストアにてカスタムロケーションを指定して、バケットを今回作成したapp-bucketを指定します。
続いて、ソースステージを追加します。
下記にて設定します。
ビルドステージは、今回作成していないのでスキップします。
続いて、デプロイステージを追加します。
赤枠の箇所をそれぞれ指定します。
最後に確認画面をチェックして、作成完了です。
これでmasterブランチにpushすると自動でデプロイが実行されます。
試しにmasterブランチにpushすると、自動でCodePipelineが実行されました。
Sourceは成功、Deployは失敗でした。
Deployに関しては、筆者は40回程繰り返して、エラー解消しつつ成功しました。
今回紹介しているコードを使用すれば、もっと少ない回数で成功できると思います。
本編は以上です。お疲れ様でした。