2
2

More than 3 years have passed since last update.

【 Ruby on Rails 6.0 】 AWS + Nginx + Unicornでデプロイ⑦

Last updated at Posted at 2021-02-26

始めに

前回の内容でNginxというWebサーバーを導入しRailsアプリを本番環境で起動出来ました。
しかし、現状だと開発環境で変更したものを本番環境に反映させるのに工数が多く不便です。
そこで、Capistranoという自動デプロイツールを導入しコマンドひとつでデプロイ作業を完了できるように設定していきます。

目次

目次 内容
セクション1 EC2インスタンス作成
セクション2 Linuxサーバー構築
セクション3 データベース設定
セクション4 EC2上でGemをインストールし環境変数を設定
セクション5 Railsアプリを起動
セクション6 Nginxの導入
セクション7 自動デプロイ(今回の内容)
セクション8 独自ドメイン取得

Capistranoの導入

必要なGemをインストールし、Capistranoを動かすために必要な設定ファイルを生成します。

Gemfile(ローカル)
group :development, :test do
  gem 'capistrano'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano-rails'
  gem 'capistrano3-unicorn'
end
ターミナル(ローカル)
$ bundle install

# gemを読み込めたら、下記のコマンドを打ちます。
$ bundle exec cap install

するとデプロイについての設定を書くファイルが自動で生成されます。

Capfileを編集

Capfileは、capistrano全体の設定ファイルです。

Capifile
require "capistrano/setup"
require "capistrano/deploy"
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
require 'capistrano3/unicorn'

Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

デプロイについての設定ファイルを編集

cap installコマンドを打つと、config/deploy配下にproduction.rbとstaging.rbの2 種類のファイルが生成されます。

production.rbですが2つファイルがあります
❌ config/environment/production.rb
⭕️ config/deploy/production.rb

今回作業はするのはconfig/deploy/production.rbです。

production.rbを下記のように編集

config/deploy/production.rb
# 最下部に追記
server 'XX.XXX.XX.XXX(Elastic IP)', user: 'ec2-user', roles: %w{app db web}

deploy.rbを編集

config/deploy.rb
# 全て削除して以下を追記
# config valid only for current version of Capistrano
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock '○.○○.○(Capistranoのバージョン)'

# Capistranoのログの表示に利用する
set :application, '○○○(自身のアプリケーション名)'
set :deploy_to, '/var/www/○○○(アプリ名)'

# どのリポジトリからアプリをpullするかを指定する
set :repo_url,  'git@github.com:○○○(Githubのユーザー名)/○○○(レポジトリ名.git'

# バージョンが変わっても共通で参照するディレクトリを指定
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads')

set :rbenv_type, :user
set :rbenv_ruby, '○.○.○(rubyのバージョン)' #カリキュラム通りに進めた場合、2.5.1か2.3.1です

# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
                  keys: ['~/.ssh/○○○○○.pem(ローカルPCのEC2インスタンスのSSH鍵(pem)へのパス 例:~/.ssh/key_pem.pem))'] 

# プロセス番号を記載したファイルの場所
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }

# Unicornの設定ファイルの場所
set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5

# デプロイ処理が終わった後、Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end

以下の5点は書き換えが必須です。

  1. 3行目のはご自身のバージョンを記述しましょう。
  2. 6行目の<自身のアプリケーション名>はご自身のものを記述しましょう。
  3. 9行目の/<レポジトリ名>も同様に、ご自身のもの記述してください。
  4. 15行目の<このアプリで使用しているrubyのバージョン>はご自身のものを確認して 記述してください。
  5. 19行目の<ローカルPCのEC2インスタンスのSSH鍵(pem)へのパス>も同様に、ご自 身のもの記述してください。

Capistranoのバージョン確認

capistranoのバージョンは、gemfile.lockに記載されています。
capistrano(3.11.0)ように記載されています。

rubyのバージョンの確認

ローカルのターミナルで以下のように確認します。

ターミナル
$ ruby -v

# 実行結果
ruby2.6.5....

unicorn.rbの記述を編集

capistrano導入後はアプリケーションのディレクトリ構造が変化するので以下のように記述を編集します。

config/unicorn.rb
app_path = File.expand_path('../../', __FILE__)

worker_processes 1

working_directory app_path
pid "#{app_path}/tmp/pids/unicorn.pid"
listen "#{app_path}/tmp/sockets/unicorn.sock"
stderr_path "#{app_path}/log/unicorn.stderr.log"
stdout_path "#{app_path}/log/unicorn.stdout.log"




# 以下のように変更↓




# ../が一つ増えている
app_path = File.expand_path('../../../', __FILE__)

worker_processes 1
# currentを指定
working_directory "#{app_path}/current"

# それぞれ、sharedの中を参照するよう変更
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"
pid "#{app_path}/shared/tmp/pids/unicorn.pid"
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"

Nginxの設定ファイルの記述を編集

同様に、Nginxの設定ファイルもディレクトリで構造が変化しているので編集します。

ターミナル(EC2)
# SSHログインしてから実行
[ec2-user@ip-172-31-25-189 ~]$ $ sudo vim /etc/nginx/conf.d/rails.conf
rails.conf
upstream app_server {
  # sharedの中を参照するよう変更(/shared/tmp/sockets/unicorn.sock;)
  server unix:/var/www/○○○○○(アプリケーション名/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name XX.XXX.XXElastic IP;

  # currentの中を参照するよう変更(/current/public;)
  root /var/www/○○○○○(アプリケーション名/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
    # currentの中を参照するよう変更(/current/public;)
    root   /var/www/○○○○○○(アプリケーション名/current/public;
  }

  try_files $uri/index.html $uri @unicorn;

  location @unicorn {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    proxy_pass http://app_server;
  }

  error_page 500 502 503 504 /500.html;
}

編集し終わったら、escキーを押して:wqで保存します。
Nginxの設定を変更したら、忘れずに再読込・再起動をします。

ターミナル(EC2)
# nginx起動
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl reload nginx
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl restart nginx


# nginxのステータスを確認(active runningであれば成功)
$ sudo systemctl status nginx.service
 nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: active (running) since  2021-02-17 11:28:00 UTC; 7h ago


# エラーが出た場合はnginxのエラーログを確認
[ec2-user@ip-172-31-45-167 アプリ名]$ sudo cat /var/log/nginx/error.log

データベースの起動を確認

データベースが立ち上がっていないとデプロイが失敗するので起動します。

ターミナル(EC2)
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl restart mariadb

# ステータスを確認(active runningなら成功)
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl status mariadb

unicornのプロセスをkill

自動デプロイを実行する前にunicornのコマンドをkillします。

ターミナル(EC2)
# プロセスを確認
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ ps aux | grep unicorn

ec2-user 17877  0.4 18.1 588472 182840 ?       Sl   01:55   0:02 unicorn_rails master -c config/unicorn.rb -E production -D
ec2-user 17881  0.0 17.3 589088 175164 ?       Sl   01:55   0:00 unicorn_rails worker[0] -c config/unicorn.rb -E production -D
ec2-user 17911  0.0  0.2 110532  2180 pts/0    S+   02:05   0:00 grep --color=auto unicorn

# 一番上のunicorn_rails masterをkillしたいので、下記を実施
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill 17877

ローカルでの修正を全てmasterにpush

ローカルでのコードの変更が、全てmasterにpushされていることを確認しましょう。

自動デプロイ実行

これで、ローカルのターミナルからコマンド一発でデプロイできるようになりました。

ターミナル(ローカル)
# アプリケーションのディレクトリで実行する
$ bundle exec cap production deploy

エラーがなく完了したらデプロイ完了です!
スクリーンショット 2021-02-27 7.41.00.png

ブラウザからElastic IPでアクセスすると、アプリケーションにアクセスできます!
確認してみましょう。

もし途中でエラーが出たら

  • EC2のターミナルでless log/unicorn.stderr.logコマンドでエラーログを確認
  • ローカルでの編集のpushやpullを忘れていないか確認
  • mariaDBやNginxを再起動してみる
  • EC2インスタンスを再起動してみる

終わりに

ここまででRailsアプリを本番環境にデプロイする工程が終了しました!
ただ、IPアドレスだと覚えにくいので次回で独自ドメインを取得方法をまとめたいと思います。
お疲れさまでした。。。

次回
独自ドメイン取得

2
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2