EC2 + RDS + Capistrano + unicorn + nginxでrailsアプリを自動デプロイ メモ

#事前準備
Githubアカウント、AWSアカウントを作成済

#概要
capistanoで以下の行程を自動化する

1.**EC2インスタンスにSSH接続をする**
2.**EC2インスタンスにGithub からpullする**
3.**アセットのコンパイルをする**
4.**Unicornの再起動をする**

すなわち一度デプロイした後に変更を行い、その変更を反映させる手順は下記になる。

1.**アプリを編集する**
2.**git commitをする**
3.**ブランチを切っている場合はmergeする**
4.**GitHubのmasterブランチへpushする**
5.**ローカルのターミナルで自動デプロイコマンドを打つ(caspitranoのコマンド)**

通常AWSにアプリをデプロイする場合サーバー側にログインしgitで変更したコードをクローンしサーバーを起動しなおすといったことが必要なので、Capistranoを使用すると大幅にデプロイの手間を削減することが可能。

本記事では一度、caspitranoを用いずにデプロイした後、caspitranoを用いて自動デプロイする。

また、Circle CI,Rspec を組み合わせれば自動テスト＆自動デプロイが可能になる。

本記事では特に記載がなければホームディレクトリでコマンド実行

#VPCの作成
まずはVPCの作成から行う。
下記のように項目を設定

|設定項目 |設定  |
|---|---|
|名前タグ |product_vpc|
|CIDR |10.0.0.0/16|
|テナンシー|デフォルト|

#サブネットの作成

これはVPC内外の通信グループを目的に応じて個別設定するものとなっています。

今回は「VPC内のRDSとプライベートに行う通信」と「localやインターネットで行うパブリックな通信」の2種類(RDSは2つなので合計3つ)のサブネットを作成していく

###パブリックサブネット(EC2用)###

|設定項目 |設定  |
|---|---|
|VPC |product_vpc|
|サブネット名|product_public_subnet_for_EC2|
|アベイラビリティゾーン|ap-northeast-1a|
|CIDR |10.0.0.0/20|
|テナンシー|デフォルト|



###プライベートサブネット(RDS用)###

|設定項目 |設定  |
|---|---|
|VPC |product_vpc|
|サブネット名|product_private_subnet_for_RDS1|
|アベイラビリティゾーン|ap-northeast-1a|
|CIDR |10.0.64.0/20|
|テナンシー|デフォルト|

|設定項目 |設定  |
|---|---|
|VPC |product_vpc|
|サブネット名|product_private_subnet_for_RDS2|
|アベイラビリティゾーン|ap-northeast-1c|
|CIDR |10.0.80.0/20|
|テナンシー|デフォルト|

#インターネットゲートウェイの作成

インターネットとの入り口である「インターネットゲートウェイ」を設定しないと通信を行うことができない。

**名前を決める**

![スクリーンショット 2021-08-27 17.05.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/8a1277d3-415d-594a-36b8-c2c37da17ace.png)

**VPCにアタッチ**
![スクリーンショット 2021-08-27 17.06.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/a3c063d3-a7e3-a002-e617-284e719e293b.png)

#ルートテーブルの作成

**サブネットが設定し終わったのでサブネットとインターネットを繋ぐルートを作成**

![スクリーンショット 2021-08-27 17.59.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/52ed25e1-eae8-0fda-7eda-ed1311232888.png)

**作成後編集**

![スクリーンショット 2021-08-27 18.00.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/83821709-be9a-18c1-b6ca-a94b9913ecde.png)

**パブリックサブネットに関連づけ**

![スクリーンショット 2021-08-27 18.04.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/5a352cfa-0913-71d4-d7fb-4038e564000d.png)


![スクリーンショット 2021-08-27 18.03.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/97bf3f3e-d8da-80dc-49ca-a4f4a938a71f.png)

**EC2のセキュリティグループ**

下記のように設定

![スクリーンショット 2021-08-27 18.26.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/177cfea9-64f3-e6fd-f39c-278c9340cce0.png)

アウトバウンドルールは設定不要だと思ったが必要だったのでのちに設定

HTTPは一般的なWebページをやり取りする普通の通信。

対してSSH通信はより安全性の高い通信になっています。
基本的にこれからはSSH通信を使ってサーバーとやり取りをしていくので必ず設定。

画像の最後のICMP - IPv4は無くても可


ここまで設定できればVPCの設定は完了。


#EC2

起動する際の設定項目

|設定項目 |設定  |
|---|---|
|ステップ1 Amazon マシンイメージ|Amazon Linux 2 AMI |
|ステップ2 インスタンスタイプの選択|t2.micro(無料利用枠)|
|ステップ3 インスタンスの詳細の設定 |ネットワークをproduct-vpc,サブネットをproduct-public-subnet,自動割り当てパブリックを有効に設定。他はデフォルト|
|ステップ4 ストレージ|デフォルト|
|ステップ5 タグ|Name product-ec2|
|ステップ6 セキュリティグループ|Security_for_product_app_EC2|

キーペアをダウンロードして起動。
EC2の作成はこれで終了です。
#RDS

サブネットを二つ作成したが、今回は一つのアベイラビリティーゾーンの中のサブネットにRDSを作成。
（無料枠を使用するため）
**セキュリティグループの作成**


|設定項目 |設定  |
|---|---|
|セキュリテイグループ名| product-db-group|
|説明|product-db-group|
|vpc|product-vpc|

インバウンドを下記のように設定
**ソースにEC2に使用したセキュリティグループを使う。これによってそのセキュリティグループ(Security_for_product_app_EC2)内のインスタンス、product-ec2のみがRDSにアクセスできる。**
![スクリーンショット 2021-08-28 18.45.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/e5372948-a98e-45e8-8b03-53dfd0fbd277.png)






**パラメータグループの作成**

|設定項目 |設定  |
|---|---|
|パラメータグループファミリー|myaql8.0|
|グループ名|product-db-pg|
|説明|product parameter group|

**オプショングループの作成**

|設定項目 |設定  |
|---|---|
|名前|mysql8.0|
|説明|product option group|
|エンジン|mysql|
|メジャーエンジンバージョン|8.0|

**サブネットグループの作成**

|設定項目 |設定  |
|---|---|
|名前|product-db-subnet|
|説明|product db subnet|
|vpc|product_vpc|

アベイラビリティゾーンはプライベートサブネットがあるゾーンを選択
サブネットはプライベートサブネットを選択

![スクリーンショット 2021-08-28 14.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/45cee97f-f97d-580f-434f-52bc04158caf.png)

**データベースを作成**

|設定項目 |設定  |
|---|---|
|データベースの作成方法|標準作成|
|エンジンの|オプション|
|バージョン|8.0.2.0|
|テンプレート|無料利用枠|
|DBインスタンス識別子|database-product|
|マスターユーザー名|任意|
|マスターパスワード|任意|
|DBインスタンスクラス|バースト可能クラス,db.t2.micro|
|ストレージ|デフォルトのまま|
|可用性と耐久性|無料利用枠なのでマルチAZできないのでデフォルトのまま|

接続について


|設定項目 |設定  |
|---|---|
|VPC|product_vpc|
|サブネット|product-db-subnet|
|パブリックアクセス|なし|
|セキュリティグループ|product-db-group|
|アベイラビリティゾーン|任意|
|データベース認証|パスワード認証|



#Elastic IP
Elastic IP を作成し、先程のインスタンスに関連づけ
関連づけの際のプライベートIPは空白でも良い

#EC2 にSSH接続

下記コマンドで権限を所有者のみに変更

```
chmod 600 ~/Desktop/product.pem
```

下記コマンドで接続

```
ssh -i ~/Desktop/product.pem ec2-user@<public IP>
```

下記のようなターミナルになる
![スクリーンショット 2021-08-28 16.24.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/3e4782b5-2130-b53d-506c-4518e4aaaa7c.png)

#nodejs Ruby ミドルウェアのインストール

アウトバウンドルールを追加しないとうまくいかないことがあります。
自分は下記設定でうまくいきました。

HTTP,HTTPS,そしてmysqlに接続するためのMYSQL/Auroraが必要です。
MYSQL/Auroraの送信先はproduct-db-group(RDSのセキュリティグループ)にします。

これによりproduct-db-group内のデータベースにアクセス可

![スクリーンショット 2021-08-28 20.07.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/aafe70cf-cee9-f898-15f4-ba8410963da0.png)




###パッケージのアップデート###

```
[ec2-user@ip-<IP アドレス> ~]$ sudo yum update -y
```

###ミドルウェアのインストール###

```
[ec2-user@ip-<IP アドレス> ~]$ sudo yum -y install git gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel libffi-devel libxml2 libxslt libxml2-devel libxslt-devel sqlite-devel libcurl-devel mysql mysql-devel ImageMagick
```

###Nodejsをインストール###

バージョン指定

```
[ec2-user@ip-<IP アドレス> ~]$ sudo curl -sL https://rpm.nodesource.com/setup_12.x | sudo bash -
```

インストール

```
[ec2-user@ip-<IP アドレス> ~]$ sudo yum install -y nodejs
```
###yarn のインストール###

```
[ec2-user@ip-<IP アドレス> ~]$ curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | sudo tee /etc/yum.repos.d/yarn.repo

[ec2-user@ip-<IP アドレス> ~]$ sudo yum -y install yarn
```

###rbenv、ruby-build、Rubyをインストール###

下記を順に実行

```
[ec2-user@ip-<IP アドレス> ~]$ git clone https://github.com/sstephenson/rbenv.git ~/.rbenv

[ec2-user@ip-<IP アドレス> ~]$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile

[ec2-user@ip-<IP アドレス> ~]$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

[ec2-user@ip-<IP アドレス> ~]$ source .bash_profile

[ec2-user@ip-<IP アドレス> ~]$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build

#必要なバージョンをインストール
[ec2-user@ip-<IP アドレス> ~]$ rbenv install 2.5.9

#インストールしたrubyを使用可能にする
[ec2-user@ip-<IP アドレス> ~]$ rbenv rehash
# このインスタンスで使用するバージョンの設定
[ec2-user@ip-<IP アドレス> ~]$ rbenv global 2.5.9
```

#Mysqlの接続確認

```
[ec2-user@ip-<IP アドレス> ~]$ mysql -h <RDSのエンドポイント> -u admin -p
```
パスワード入力後下記画面になる

```
MySQL [(none)]>
```
exit で出る

#アプリをEC2にクローン


EC2インスタンスのSSH鍵をGithubに登録すると、Githubはそれを認証してクローンの許可を出す。
SSH接続でgit clone ができる。

###EC2サーバのSSH鍵ペアを作成###

```
[ec2-user@ip-<IP アドレス> ~]$ ssh-keygen -t rsa -b 4096
```

下記のようになれば成功

```
The key's randomart image is:
+---[RSA 4096]----+
|   .o    o o     |
|  .  o  . o +    |
| . .  =o.. . o  .|
|  o...oB=o. . . o|
| o.ooo=oS. . o .E|
|  +o.o.o.B .o .  |
|....  ..  *..    |
|..o  .   . o     |
| . ..            |
+----[SHA256]-----+
```

SSH公開鍵を表示し、値をコピーするため、下記コマンドを実装

```
[ec2-user@ip-<IP アドレス> ~]$ cat ~/.ssh/id_rsa.pub
```

###コピーした公開鍵をGithubにアクセスして登録する###

[https://github.com/settings/keys](https://github.com/settings/keys)にアクセス

new ssH key でコピーしたkey を登録

###設定ファイルを編集###

```
[ec2-user@ip-<IP アドレス> ~]$ vi ~/.ssh/config
```

下記を記載

```
Host github.com
    Hostname ssh.github.com
    Port 443
    IdentityFile ~/.ssh/id_rsa
    User git
```

権限変更

```
[ec2-user@ip-<IP アドレス> ~]$ chmod 600 ~/.ssh/config
```

確認するコマンド

```
[ec2-user@ip-<IP アドレス> ~]$ ssh -T git@github.com
```

下記のようになれば接続完了

```
Hi ryotaro-tenya0727! You've successfully authenticated, but GitHub does not provide shell access.
```

###App側でunicorn インストール###

こちらはローカルで行う
EC2にGit クローンする前に、準備としてUnicornをインストールさせる
Gemfileにgem'unicorn'を追加

```
group :production do
  gem 'unicorn', '5.4.1'
end
```

```
bundle install
```

config/unicorn.rbを作成

追加したunicorn.rbに下記を記述

```ruby:config/unicorn.rb
# rootパスのディレクトリを指定
root_path = File.expand_path('../../', __FILE__)

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

# アプリケーションの設置されているディレクトリを指定
working_directory root_path

# プロセスIDの保存先を指定
pid "#{root_path}/tmp/pids/unicorn.pid"

# ポート番号を指定
listen "#{root_path}/tmp/sockets/unicorn.sock"

# エラーのログを記録するファイルを指定
stderr_path "#{root_path}/log/unicorn.stderr.log"

# 通常のログを記録するファイルを指定
stdout_path "#{root_path}/log/unicorn.stdout.log"

#応答時間を待つ上限時間を設定
timeout 30

# ダウンタイムなしでUnicornを再起動時する
preload_app true

GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true

#アプリケーションを読み込む前に呼ぶ前に、unicornの接続が
#同じホスト上のクライアントに限定された状態になっているかチェックする。
#切断された接続に対してアプリケーションを呼び出すのを防ぐ
check_client_connection false

run_once = true

#この設定をしておけば、再起動時に古いプロセスをkillしてくれる。
before_fork do |server, worker|
  defined?(ActiveRecord::Base) &&
    ActiveRecord::Base.connection.disconnect!

  if run_once
    run_once = false # prevent from firing again
  end

  old_pid = "#{server.config[:pid]}.oldbin"
  if File.exist?(old_pid) && server.pid != old_pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH => e
      logger.error e
    end
  end
end

after_fork do |_server, _worker|
  defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
end
```

**記入ができたらcommitし、masterにpush**

###アプリケーションの保存先となるディレクトリを作成###

ディレクトリの作成

```
sudo mkdir /var/www/
```

###作成したディレクトリをchownコマンドで権限設定,wwwディレクトリに移動###

```
[ec2-user@ip-<IP アドレス> ~]$ sudo chown ec2-user /var/www/

[ec2-user@ip-<IP アドレス> ~]$ cd /var/www
```

###アプリを git clone###

```
[ec2-user@ip-<IP アドレス> www]$git clone <sshのURL>
```

###gem のインストール###

ローカルと同じバージョンのbundlerをインストール

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ gem install bundler -v 1.17.3
```

gem をインストール

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ bundle install
```

#環境変数の設定

##環境変数とは？##
環境変数は簡単に説明すると、PWを公開しないための変数。

Githubは開発するに際に非常に便利
コードのバックアップのような役割も担うし、他の開発チームとコードを共有することができる。

しかし、PWは公開したくない。
このPW（パスワード）などの公開したくない情報を環境変数というもので隠す。

変数はX=3のように 文字（X）の意味（３）を定義。
環境変数の場合、環境変数 = 'PW' のように、パスワードを変数の値とする。
こうすることで、コードに記述されている環境変数だけでは、パスワードを特定できないので、
悪用されない仕組みとなる。

環境変数で定義したPWは、開発者のみが’鍵（暗号化を解除するための数値）’を持っており、鍵を持っている人間しか、実際の値をみることができない.

##secret_key_baseの取得##

secret_key_baseは「railsアプリ」でクッキーを暗号化するものになります。
クッキーとは、webを参照した時の履歴のようなものを残し、次回から素早くアクセスできるものになります。
クッキーは外部から参照されるとよくないので暗号化します。

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ rake secret
```

この結果表示された暗号をコピーしておきます。

##環境変数の設定##

環境変数を記述する場所を開きましょう

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ sudo vim /etc/environment
```

/etc/environment に環境変数を設定するとインスタンス全体に反映されます。

ファイルを開いたら環境変数を定義します。

```
DATABASE_PASSWORD='MySQLのマスターユーザーのパスワード'
SECRET_KEY_BASE='先程コピーしたsecret_key_base'
```

vim はi で入力
入力後、esc =>:wq で保存して画面が戻ります。

設定した環境変数を反映させるために、一度本番環境を **exit** でログアウトしましょう。

###環境変数が無事に設定されているか確認###

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ env | grep SECRET_KEY_BASE
SECRET_KEY_BASE='secret_key_base'

[ec2-user@ip-<IP アドレス> <アプリ名>]$ env | grep DATABASE_PASSWORD
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
```

###master.keyの設定###

先ほど環境変数を定義するところでRAILS_MASTER_KEYの値もセットしておきましょう。
セットする値はconfig/master.keyファイルの中身です。

```
sudo vi /etc/environment

# 編集モードで以下を追記
RAILS_MASTER_KEY="master.keyの中身"
```

###database.ymlの編集###

localで編集。

database: のところはアプリ名でもなんでも良い
usernameはRDSのマスターユーザー、またはMYSQL で作成したユーザー。


```yml:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  port: 3306
  pool: <%= ENV.fetch("RAILS_MAX_THREADS"){5}%>
  username: admin

development:
  <<: *default
  database: product_register_new_development 

test:
  <<: *default
  database: product_register_new_test

production:
  <<: *default
  database: product_register_new_production
  password: <%= ENV['DATABASE_PASSWORD']%>
  socket: /var/lib/mysql/mysql.sock
　　　　host: <RDSのエンドポイント>

```

設定したらgit commit して git push 

EC2 でgit pull

#Nginxの設定

EC2インスタンスで実行（nginx の設定ファイルはアプリケーションのディレクトリにないため。git管理してない)
下記コマンドでNginx インストール

```
[ec2-user@ip-<IP アドレス> ~]$ sudo amazon-linux-extras install nginx1
```

Nginx のバージョン確認

```
[ec2-user@ip-<IP アドレス> ~]$ nginx -v
```

Nginxを起動

```
[ec2-user@ip-<IP アドレス> ~]$ sudo systemctl start nginx
```
http://<パブリックIPアドレス>にアクセスすると下記画面になります。

![スクリーンショット 2021-08-29 15.17.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1461885/b8855c04-eec1-49a2-d4b4-149e41bca999.png)


##設定ファイルを編集##

次はNginxにアクセスされた時の動作を設定するファイルの編集を行う
それぞれの設定ファイルは**/etc/nginx**ディレクトリに格納されている
デフォルトの設定は**nginx.conf**ファイルで定義されている

**nginx.conf**内に**include /etc/nginx/conf.d/*.conf;**という記述があるので、設定ファイルは**etc/nginx/conf.d**ディレクトリ内に今回は**rails.conf**というファイル名で作成します。

下記のコマンドを実行して設定ファイルの作成と編集をしていきます。

```
[ec2-user@ip-<IP アドレス> ~]$ sudo vi /etc/nginx/conf.d/rails.conf
```

```rails.conf
upstream unicorn {
  server unix:/var/www/クローンするリポジトリ名/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name ご自身のElastic IPアドレス;
  root /var/www/クローンするリポジトリ名/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  location @unicorn {
    proxy_set_header Host                   $host;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Real-IP        $remote_addr;
    proxy_set_header X-Forwarded-For      $remote_addr;
    proxy_redirect off;
    proxy_pass http://unicorn;
  }

  try_files $uri @unicorn;
  error_page 500 502 503 504 /500.html;
  error_page 404             /404.html;

  location = /404.html {
        internal;
  }
  location = /500.html {
        internal;
  }
}
```

#アセットファイルをコンパイル

まずはcssやJavaScript、画像ファイルのコンパイルを行います。
ローカル環境ではこの作業は不要でしたが、本番環境では処理速度の関係で自動的に行われないので随時行う必要があります。
下記のコマンドでアセットファイルをコンパイルします。

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ rails assets:precompile RAILS_ENV=production
```

#データベース作成

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ rails db:create RAILS_ENV=production

[ec2-user@ip-<IP アドレス> <アプリ名>]$ rails db:migrate RAILS_ENV=production

```

#Rails を起動

それではいよいよEC2インスタンス内でRailsを起動させます。

その前に一度Nginxを再起動させましょう。

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ sudo systemctl reload nginx

[ec2-user@ip-<IP アドレス> <アプリ名>]$ sudo systemctl start nginx

[ec2-user@ip-<IP アドレス> <アプリ名>]$ unicorn_rails -c config/unicorn.rb -E production -D
```

パブリックIPをブラウザに入力し、アプリケーションが表示されれば成功。

#Capistranoで　自動化

ローカルで行います。
###gem をインストール###

Gemfileに下記を追加

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

**capistrano-rbenv**	: Capistranoでrbenvでインストールしたrubyを使用可能にする
**capistrano-bundler**	: Capistranoで自動でbundle installを可能にする
**capistrano-rails**	: Capistranoでマイグレーションやアセットのコンパイルを可能にする
**capistrano3-unicorn**	: CapistranoでUnicornの再起動などを可能にする

```
[<アプリ名>]$ bundle install
```

次に下記コマンド実行

```
[<アプリ名>]$ bundle exec cap install
```

ファイルができる

```
mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified
```

###Capfile を編集###

Capfileを下記のように編集

```Capfile:Capfile
require "capistrano/setup"
require "capistrano/deploy"
require "capistrano/rbenv"
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
require "capistrano3/unicorn"
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }
```
###deploy.rbを編集###

下記のように編集

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

# アプリケーションの指定
set :application, 'レポジトリ名'
set :repo_url,  'git@github.com:Githubのユーザー名/レポジトリ名.git'

# sharedディレクトリに入れるファイルを指定
append :linked_dirs, "log", "tmp/pids", "tmp/cache", "tmp/sockets", "vendor/bundle", "public/system", "public/uploads"

# SSH接続設定
set :ssh_options, {
  auth_methods: ['publickey'], 
  keys: ['~/.ssh/プライベートキーの名前.pem'] 
}

# 保存しておく世代の設定
set :keep_releases, 5

# rbenvの設定
set :rbenv_type, :user
set :rbenv_ruby, 'アプリで使用しているrubyのバージョン'

# ここからUnicornの設定
# Unicornのプロセスの指定
set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" }

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

# Unicornを再起動するための記述
after 'deploy:publishing', 'deploy:restart'
namespace :deploy do
  task :restart do
    invoke 'unicorn:restart'
  end
end
```

###production.rbの編集###

```ruby:config/deploy/production.rb
server 'Elastic IPアドレス', user: 'ec2-user', roles: %w{app db web}
```

###ディレクトリ構成について###

先ほどdeploy.rbの記述内に「sharedディレクトリに入れるファイルを指定」というのがありました。
「sharedディレクトリ」とはCapistranoの自動デプロイ時に本番環境のディレクトリに新しく自動で追加されるディレクトリの１つです。

自動で作成されるディレクトリはこれを含めて3つあるので確認しておきましょう。

|追加されるディレクトリ |役割  |
|---|---|
|current|現在デプロイされている内容が保管されている|
|releases|過去にデプロイした内容が保管されている|
|shared|バージョンに関係なく参照される内容が保管されている|


自動デプロイ作業によりディレクトリ構成が変化するので、それに応じて変更するファイルがあります。

ここからEC２インスタンスで行います。

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

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ sudo vim /etc/nginx/conf.d/rails.conf
```

下記のように編集

```/etc/nginx/conf.d/rails.conf:/etc/nginx/conf.d/rails.conf 
upstream unicorn {
// shared内に変更
  server unix:/var/www/クローンするリポジトリ名/shared/tmp/sockets/unicorn.sock;
}

server {
  listen 80;
  server_name ご自身のElastic IPアドレス;
// current内に変更
  root /var/www/クローンするリポジトリ名/current/public;

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  location @unicorn {
    proxy_set_header Host                   $host;
    proxy_set_header X-Forwarded-Host       $host;
    proxy_set_header X-Forwarded-For      $remote_addr;
    proxy_set_header X-Real-IP        $remote_addr;
    proxy_redirect off;
    proxy_pass http://unicorn;
  }

  try_files $uri @unicorn;
  error_page 500 502 503 504 /500.html;
  error_page 404             /404.html;

  location = /404.html {
        internal;
  }
  location = /500.html {
        internal;
  }
}
```

###unicorn.rbの編集###

ローカルで行います

```ruby:config/unicorn.rb
# rootパスのディレクトリを指定（「../」が先頭に追加）
root_path = File.expand_path('../../../', __FILE__)

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

# アプリケーションの設置されているディレクトリを指定（current内に変更）
working_directory "#{root_path}/current"

# プロセスIDの保存先を指定（shared内に変更）
pid "#{root_path}/shared/tmp/pids/unicorn.pid"

# ポート番号を指定（shared内に変更）
listen "#{root_path}/shared/tmp/sockets/unicorn.sock"

# エラーのログを記録するファイルを指定（shared内に変更）
stderr_path "#{root_path}/shared/log/unicorn.stderr.log"

# 通常のログを記録するファイルを指定（shared内に変更）
stdout_path "#{root_path}/shared/log/unicorn.stdout.log"

# 以下略
```

これで準備は完了です。
今までの編集を反映させるため、commitしGitHubへpushしましょう。

#自動デプロイ

設定ファイルを色々と変更したので、Nginxの再起動をします。

```
[ec2-user@ip-<IP アドレス> <アプリ名>]$ sudo systemctl reload nginx
[ec2-user@ip-<IP アドレス> <アプリ名>]$ sudo systemctl restart nginx
```

ローカルのアプリケーションのディレクトリで下記を実行します。

```
[<アプリ名>]$ bundle exec cap production deploy
```

ブラウザにパブリックIPを入力して表示されれば成功です。

Nginx設定ファイルを変更した場合、Nginxの再起動が必要になります。

**これ以降、インスタンスに接続して、色々いじったりすると接続できなくなることがあります。
下記の手順を守るのが良いと思われます。
1.アプリを編集する
2.git commitをする
3.ブランチを切っている場合はmergeする
4.GitHubのmasterブランチへpushする
5.ローカルのターミナルで自動デプロイコマンドを打つ(caspitranoのコマンド)**