自動デプロイ（Capistrano）の導入

#はじめに

先日AWSを利用して、アプリケーションのデプロイを一通り終えることができたのですが、コード1つでデプロイができたCapistranoに非常に感動したので、導入方法について記事に残したいと思います。

今回は
[サルでもできる!? Rails 6のアプリをAWS EC2にデプロイするまでの全手順【前半】（VPC, RDS, EC2, Capistrano）](https://qiita.com/take18k_tech/items/5710ad9d00ea4c13ce36)
こちらの記事を参考にさせていただきました。ありがとうございました。

##環境

Rails6.0.0
Unicorn（アプリケーションサーバー）導入済み
Nginx（Webサーバー）導入済み

##Capistranoの導入

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

group :development, :test doはデフォルトでGemfile内にあると思うので、その中に5つのGemを記述して、bundle installを行い、Gemfileを読み込みます。

その後

```ruby:ターミナル（ローカル）
bundle exec cap install
```

のコマンドを実行すると、**Gapfile**や**deploy.rb**, **production.rb**などのファイルが生成されます。


##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 }
```

デフォルトでコードが書いてあるとは思いますが、それらを全て削除して、上記のコードを記述します。デプロイに関する必要な動作が記述されているファイルを、requireで読み込んでいます。


##production.rbの編集

次に先ほど生成したファイルのproduction.rbを編集していきます。

```ruby:config/deploy/production.rb
server 'Elastic IP', user: 'AWSサーバーにログインできるユーザー名(デフォルトはec2-user)', roles: %w{app db web}
```

上記を記述し、production.rbの編集は完了です。


##deploy.rbの編集

次はdeploy.rbを編集していきます

```ruby:config/deploy.rb
lock 'Capistranoのバージョンを記入'

set :application, 'アプリ名'

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のバージョン' 

set :ssh_options, auth_methods: ['publickey'],
                                  keys: ['~/.ssh/キーペア名.pem'] 

set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }

set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" }
set :keep_releases, 5

after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end
```

上記では
・Capistranoのバージョンを記入すること（Gemfile.lock内に記載されています)
・アプリケーション名を記入すること
・Githubのユーザー名、リポジトリ名を記入すること
・rubyのバージョンを記入すること
・キーペア名(EC2インスタンスにログインするために必要な秘密鍵）を記述すること

を注意してコードの記述を行なってください。1つ1つのコードの役割については、長くなるので今回は割愛します。


##Unicornの設定ファイル編集

既にUnicornを導入済みであれば、自動デプロイ時にはRailsのアプリケーションディレクトリが1段深くなっているため、少し修正をします。

```ruby:config/unicorn.rb

app_path = File.expand_path('../../../', __FILE__) #[../]を1つ増やす
worker_processes 1
working_directory "#{app_path}/current" #currentを指定
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の設定ファイルと同じように修正します。

```ruby:ターミナル（サーバー環境）
$ sudo vim /etc/nginx/conf.d/'アプリ名'.conf
```

「i」を打ち込んでinsertモードとしてから

```ruby:/etc/nginx/conf.d/'アプリ名'.conf
upstream app_server {
  server unix:/var/www/アプリケーション名/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name Elastic IP;
  client_max_body_size 2g;
  root /var/www/アプリケーション名/current/public;
  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;
}
```

上記のように編集します。

Nginxの設定を変更した場合は

```ruby:ターミナル（サーバー環境）
$ sudo systemctl reload nginx
$ sudo systemctl restart nginx
```

再起動を忘れずに！！！！


##その他の確認

データベースの起動を確認しておきます。

```ruby:ターミナル（サーバー環境）
$ sudo systemctl status '使用するデータベース' 
```

Unicornのプロセスをkillします。二重でサーバーを立ち上げるのを防ぐためです。

```ruby:ターミナル（サーバー環境）
...(リポジトリ名）]$ps aux | grep unicorn 
```

のコマンドでmasterのプロセス番号を確認後、

```ruby:ターミナル（サーバー環境）
...(リポジトリ名）]$ kill プロセス番号 
```

以上で準備は完了です。


##緊張の瞬間・・・

```ruby:ターミナル（ローカル）
% bundle exec cap production deploy
```

デプロイ中はどこかで止まって、エラーが表示されないかとヒヤヒヤしていましたが、無事にデプロイ完了です。これで臆せず既存のアプリケーションの修正・改善ができるようになります！！！！

間違っている点などありましたら、ご指摘ください。