[Rails] Capistranoを使って自動デプロイできるようにする

##はじめに
Capistranoを使って、アプリを改修や変更を加えたときに、コマンド一つで自動でデプロイできるようにしましたので、行った方法を残しておきます。

前回の続きとして捉えていただければ大丈夫です。
よろしくお願いします。

##Capistrano導入

まずはCapistranoを導入するために必要なGemを追加します。
Gemfileの```group :development, :test do ~ end ```の中に下記の記述を記入します。

```ruby:Gemfile
（省略）

group :development, :test do
  gem 'capistrano'
  gem 'capistrano-rbenv'
  gem 'capistrano-bundler'
  gem 'capistrano-rails'
  gem 'capistrano3-unicorn'
end

（省略）
```

記述できたら、bundle install

その後、下記のコマンドも実行します。

```terminal:ターミナル
# アプリケーションのディレクトリで実行しましょう
% bundle exec cap install
```

するといくつかのファイルが自動で生成されます。

##Capfileを編集
Capfileとは先程のコマンドで生成されたファイルのうちの一つです。
capistranoは複数のライブラリ(Gem)から成り立っているので、このCapfileでどのライブラリを読み込むかの指定をします。

Capfileを下記のように編集します。

```ruby:Capfile
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 }
```

##production.rbを編集
続いて、コマンドで生成されたファイルの一つであるproduction.rbを編集します。
このファイルは```config/deploy/production.rb```にあります。

このファイルの一番下に下記の記述を追記します。

```ruby:config/deploy/production.rb
server '自分のElastic IP', user: 'ec2-user', roles: %w{app db web}
```

Elastic IPは自分のものに置き換えてください。

##deploy.rbを編集
config/deploy.rbの記述を全て削除し、下記を貼り付け、さらに自分の使用している各々のツールのバージョンや情報を置き換えます。

```ruby:config/deploy.rb
# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する
lock 'Capistranoのバージョン'

# Capistranoのログの表示に利用する
set :application, 'ご自身のアプリケーション名'

# どのリポジトリからアプリを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.6.5’ です

# どの公開鍵を利用してデプロイするか
set :ssh_options, auth_methods: ['publickey'],
                                  keys: ['~/.ssh/ご自身のキーペア名.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
```

置き換える箇所は、2, 5, 8, 14, 18行目です。
二行目のCapistranoのバージョンはGemfile.lockに記載されています。

例↓

```ruby:Gemfile.lock
（省略）

capistrano (3.11.0)

（省略）
```

上記のように書かれていた場合は、2行目に「3.11.0」と記載します。


##unicorn.rbを編集する

続いて、自動デプロイの場合Railsアプリのディレクトリが一段階深くなるため、少しunicorn.rbの記述を編集します。

```ruby:config/unicorn.rb
#サーバ上でのアプリケーションコードが設置されているディレクトリを変数に入れておく
app_path = File.expand_path('../../../', __FILE__)  # 「../」が一つ増えている

#アプリケーションサーバの性能を決定する
worker_processes 1

#アプリケーションの設置されているディレクトリを指定
working_directory "#{app_path}/current"  # 「current」を指定

#Unicornの起動に必要なファイルの設置場所を指定
pid "#{app_path}/shared/tmp/pids/unicorn.pid"  # 「shared」の中を参照するよう変更

#ポート番号を指定
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"  # 「shared」の中を参照するよう変更

#エラーのログを記録するファイルを指定
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"  # 「shared」の中を参照するよう変更

#通常のログを記録するファイルを指定
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"  # 「shared」の中を参照するよう変更
（省略）
```

##Nginxの設定ファイルを編集
unicornの設定ファイルを編集した理由と同じ理由でNginxのファイルも編集します。
まずはEC2にログインした状態のターミナルで下記のコマンドを実行してエディタを立ち上げます。

```terminal:ターミナル
$ sudo vim /etc/nginx/conf.d/rails.conf
```

その後「iキー」で入力できるよにしたら、下記のように変更します。

```conf:/etc/nginx/conf.d/rails.conf
upstream app_server {
  # Unicornと連携させるための設定
  server unix:/var/www/リポジトリ名/shared/tmp/sockets/unicorn.sock;
}

# {}で囲った部分をブロックと呼ぶ。サーバの設定ができる
server {
  # このプログラムが接続を受け付けるポート番号
  listen 80;
  # 接続を受け付けるリクエストURL ここに書いていないURLではアクセスできない
  server_name Elastic IP;

  # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく
  client_max_body_size 2g;

# 接続が来た際のrootディレクトリ
  root /var/www/リポジトリ名/current/public;

# assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定
  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control 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;
}
```

3行目の「リポジトリ名」は自分のものに置き換えます。

17, 24行目は完全に新しい記述のため、気をつけてください。
入力を終えたら「escキー」→「:wq」の順で実行し、保存します。

Nginxの設定を変更したら、再読み込み、再起動を下記のコマンドで行います。

```terminal:ターミナル
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl reload nginx
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl restart nginx
```

これでNginxの編集は以上です。

##データベースの起動の確認
下記コマンドでデータベースが立ち上がっているか確認します。

```terminal:ターミナル
[ec2-user@ip-172-31-25-189 ~]$ sudo systemctl status mariadb 
```

緑色で「active」の文字が表示されていれば正常に起動しています。
もしactiveになっていない場合は```sudo systemctl start mariadb```を実行します。

##Unicornのプロセスをkill
最後に自動デプロイをする前に、二重にサーバーを立ち上げることを防ぐために、プロセスをkillしておきます。

まずはプロセスを確認します。

```terminal:ターミナル
[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
```

続いてプロセスをkill

```terminal:ターミナル
# 上記の例だと「17877」
[ec2-user@ip-172-31-23-189 <リポジトリ名>]$ kill プロセス番号
```

完了したらローカルで修正を全てmasterにプッシュします。

##自動デプロイ
ローカルのターミナルで自動デプロイは行います。
下記のコマンドをアプリのディレクトリで行います。

```terminal:ターミナル
# アプリケーションのディレクトリで実行しましょう
% bundle exec cap production deploy
```

これで自動デプロイ完了です。