Capistranoで自動デプロイ

「Capistrano」とは、自動デプロイツールと呼ばれるものの一種です
この「Capistrano」を使ってデプロイする流れを残しておきます。

#①Gemfileに追記 → bundle install → bundle exec cap install

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

``bundle exec cap install``のコマンドを打つと下記のファイルが作成される

[![Image from Gyazo](https://i.gyazo.com/7f461b0d94362bf8a4df2528cf41ee5f.png)](https://gyazo.com/7f461b0d94362bf8a4df2528cf41ee5f)

#②Capfileを編集

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

#③デプロイについての設定ファイルを編集
下記の項目を編集します

・サーバーホスト名
・AWSサーバーへのログインユーザー名
・サーバーロール(後述)
・sshの設定
・その他サーバーに紐づく任意の設定

###③-1　production.rbの一番下に追記

```production.rb
server '用意したElastic IP', user: 'ec2-user', roles: %w{app db web}
```

###③-2　deploy.rbを編集　※変更するのは下記の箇所
1.'Capistranoのバージョン' → Gemfile.lockに記載されている
2.'アプリケーション名'
3.'Githubのユーザー名/レポジトリ名'
4.'rubyのバージョン'
5.'自分のキーペア'

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

###ここでメモ...

Capistranoによるアプリのバックアップなど複数のディレクトリが作成され、
その中でも特に重要な3つのファイルがあります

####①releasesディレクトリ
capistranoを通じてデプロイされたアプリがひとまとめにされる。
ここに過去のアプリが残っていることにより、デプロイ時に何か問題が発生しても一つ前のバージョンに戻ったりすることができる。
その過去の保存数を指定しているのがdeploy.rbの「set :keep_releases」の記述。今回は5つ、過去のバージョンを保存するよう設定。

####②currentディレクトリ
releasesフォルダの中で一番新しいものが自動的にコピーされているような状態。
つまり、「現在デプロイされている内容＝current内の内容」ということになる。

####③sharedディレクトリ
バージョンが変わっても共通で参照されるディレクトリが格納されるディレクトリ。
具体的には、log、public、tmp、vendorディレクトリが格納される。

---

#④Unicornの設定ファイルを編集
手動デプロイの時と比べ、自動デプロイ時にはRailsのアプリケーションのディレクトリが1段階深くなっているため、数ヶ所変更を加える必要がある。

```config/unicorn.rb
# 「../」が一つ増えている
app_path = File.expand_path('../../../', __FILE__)

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

# 「current」を指定
working_directory "#{app_path}/current"

# 「shared」の中を参照するよう変更
listen "#{app_path}/shared/tmp/sockets/unicorn.sock"

# 「shared」の中を参照するよう変更
pid "#{app_path}/shared/tmp/pids/unicorn.pid"

# 「shared」の中を参照するよう変更
stderr_path "#{app_path}/shared/log/unicorn.stderr.log"

# 「shared」の中を参照するよう変更
stdout_path "#{app_path}/shared/log/unicorn.stdout.log"
```

---

#⑤Nginxの設定ファイルを編集

###⑤−1 エディタを立ち上げる (ターミナル EC2内）
```
$ sudo vim /etc/nginx/conf.d/rails.conf
```

###⑤−2 「i」 で編集モード → 編集 → esc → :wq
1.' server unix:/var/www/アプリ名/shared/tmp/sockets/unicorn.sock;'
2.'Elastic IP'
3.'root /var/www/アプリ名/current/public;'を丸ごと追加
4.'root /var/www/アプリ名/current/public;'

```/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 Nginxの設定を変更したら忘れず再読込・再起動 (ターミナル EC2内）

```
[ec2-user@ip-***-**-**-*** ~]$ sudo systemctl reload nginx
[ec2-user@ip-***-**-**-*** ~]$ sudo systemctl restart nginx
```

---

#⑥データベースの起動を確認 (ターミナル EC2内）

```
[ec2-user@ip-***-**-**-*** ~]$ sudo systemctl status mariadb 
```
「active」と表示されれば起動している。
「active」になっていない場合はsudo systemctl start mariadbを実行。

#⑦Unicornのプロセスをkill (ターミナル EC2内）

```
[ec2-user@ip-***-**-**-*** <リポジトリ名>]$ ps aux | grep unicorn
```
```
[ec2-user@ip-***-**-**-*** <リポジトリ名>]$ kill プロセス番号
```

#⑧ローカルでの修正を全てmasterにpush
Git Hub Desktopやらで確認する。

#⑧自動デプロイを実行(ターミナル ローカル）
アプリケーションのディレクトリで　ｶﾁｬｶﾁｬｯｯ..ﾀｰーーン

```
$ bundle exec cap production deploy
```

#⑨ブラウザからElastic IPでアクセス
Elastic IPのみ（3000いらない）でアクセス確認できたら成功！

#⑩アプリケーション修正から自動デプロイまでの流れ（必要であれば）
###⑩-1　ローカルでVSCodeを修正した場合
変更点をリモートリポジトリにcommit→pushする
（ブランチを切っている場合はmergeまで実行）

###⑩-2　ローカルでデータベース関連の内容を修正した場合
本番環境で

```ruby
rails db:drop RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1
```

```ruby
rails db:create RAILS_ENV=production DISABLE_DATABASE_ENVIRONMENT_CHECK=1
```

###⑩-3　Nginxを修正した場合
下記を実行

```
sudo systemctl restart nginx
```

###⑩-4　再度自動デプロイを実行する場合（本番環境でサーバー再起動をする場合）
一度プロセスをkillした上で下記を実行

```
bundle exec cap production deploy
```
---

以上です！お疲れ様でした。