Railsで作ったアプリをAWSでデプロイ⑥　〜Gitクローン,Unicorn導入,credentials設定〜


前回までMySQLを作成しました

Railsで作ったアプリをAWSでデプロイ⑤　〜MySQL作成〜
https://qiita.com/shunsuke284052/items/a760debce93df295a05e
Railsで作ったアプリをAWSでデプロイ④　〜EC2インスタンスの環境構築〜
https://qiita.com/shunsuke284052/items/af6957d575179bf5b11a
Railsで作ったアプリをAWSでデプロイ③　〜Elastic IP,ポート開放,EC2インスタンスログイン〜
https://qiita.com/shunsuke284052/items/fee7caf4a2ecbb49a7c7
Railsで作ったアプリをAWSでデプロイ②　〜EC2インスタンス〜
https://qiita.com/shunsuke284052/items/6de92b0f832d6240f0bb
Railsで作ったアプリをAWSでデプロイ⑤　〜MySQL作成〜
https://qiita.com/shunsuke284052/items/a760debce93df295a05e

①今回はGithubにあげている自分のアプリを本番環境にGitクローン
②AppサーバであるUnicorn導入
③鍵をおくcredentialsを設定
をやっていきます

本番環境にアプリをGitクローンするために、
本番環境でSSH鍵を作成し、Githubに登録させます
まずSSH鍵を作成します

```terminal:EC2インスタンス
ssh-keygen -t rsa -b 4096
```
３回ぐらい何か聞かれますが全てエンターで無視してください

```terminal:EC2インスタンス
cat ~/.ssh/id_rsa.pub

ssh-rsa AAAJNBJIJN988h.......
```
catコマンドで公開鍵の中身を確認します
これをコピー

Githubのアプリのあるリポジトリに行き、 「settings」→「Deploy key」→「Add deploy key」で登録できます
タイトルはご自身の好きなように設定してください

これでGitクローンが可能になりました

次にUnicornを導入していきます
Unicornは本番環境で用いられるAppサーバです

ローカルのRailsアプリのGemfileに以下を追記します

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

configに手動でunicorn.rbを作成し以下をコピペ

```ruby:config/uniorn.rb

#サーバ上でのアプリケーションコードが設置されているディレクトリを変数に入れておく
app_path = File.expand_path('../../', __FILE__)

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

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

#Unicornの起動に必要なファイルの設置場所を指定
pid "#{app_path}/tmp/pids/unicorn.pid"

#ポート番号を指定
listen 3000

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

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

#Railsアプリケーションの応答を待つ上限時間を設定
timeout 60


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

check_client_connection false

run_once = true

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

```

production.rbの下記記述をコメントアウトします
デプロイ時のエラーの原因となるようです

```rails:config/environments/production.rb
# これをコメントアウト
config.assets.js_compressor = :uglifier
```

その後、本番環境で/var/wwwディレクトリを作成し、権限をec2-userに変更します

```terminal:EC2インスタンス

[ec2-user@ip-123-12-12-123 ~]$ sudo mkdir /var/www/

[ec2-user@ip-123-12-12-123 ~]$ sudo chown ec2-user /var/www/

```

作成したwwwディレクトリでgit cloneを行います

メモリ不足でエラーを起こさないようにSWAP領域を作成します
SWAP領域はメモリ不足でエラーが生じないように一時的にメモリを拡張させることができるファイルです

```linux:EC2インスタンス
$ cd

$ sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512
# しばらく待って、以下のように表示されれば成功
512+0 レコード入力
512+0 レコード出力
536870912 バイト (537 MB) コピーされました、 7.35077 秒、 73.0 MB/秒

$ sudo chmod 600 /swapfile1

$ sudo mkswap /swapfile1
# 以下のように表示されれば成功
スワップ空間バージョン1を設定します、サイズ = 524284 KiB
ラベルはありません, UUID=74a961ba-7a33-4c18-b1cd-9779bcda8ab1

$ sudo swapon /swapfile1

$ sudo sh -c 'echo "/swapfile1  none        swap    sw              0   0" >> /etc/fstab'

```
これでSWAP領域ができました

本番環境でgemをインストールします
事前にローカルで自分のアプリに使われているbundlerのバージョンを確認してください

```terminal:/var/www/アプリ名
gem install bundler -v 確認したbundlerのバージョン
gundle install
```

railsアプリケーションのsecret_key_baseを本番環境の環境変数に入れてあげます
secret_key_baseはcookieの暗号化に用います
rails5.2以降はcredentialsというファイルにsecret_key_baseがあります

私は VisualStadiooCodeを使っているので、path内にcodeコマンドをインストールします

```rails:ローカル
EDITOR='code --wait' rails credentials:edit
```

これでcredentialsの中身が確認できます。
中身はこんな感じです

```rails:credentials
# aws:
#   access_key_id: 123
#   secret_access_key: 345

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: cba02a4f137e......

```
合わせてmaster.keyの値もコピーします

こんな感じになっています
aws周りのコメントアウトは後々使いますが、ひとまずsecret_key_baseをコピー

その後、本番環境の環境変数に入れてあげます

```
$ sudo vim /etc/environment
```
vimコマンドで直接ファイルに書き込みできます

```terminal:/env/environment
DATABASE_PASSWORD='MySQLのrootユーザーのパスワード'
SECRET_KEY_BASE='先程コピーしたsecret_key_base'
RAILS_MASTER_KEY='master.keyの値'
```
合わせてMySQLのパスワードも環境変数に入れました

ここで先ほど作成したuniorn.rbに注目するとポート番号を３０００に指定しています
AWSのポートも3000で開いてあげます

AWSのEC２インスタンスのlaunch-wizard-1を開きます
<img width="1440" alt="スクリーンショット 2020-03-11 19.16.19.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594198/c0f14a89-354a-eca3-1778-a2c3f51c29cc.png">

このようにしてカスタムTCP,3000,0.0.0.0/0でインバウンドルールを追加しました

unicornコマンドでrailsを起動させる前にdatabase.ymlを編集します

```rails:config/database.yml
production:
  <<: *default
  database: ~~~（それぞれのアプリケーション名によって異なっています。こちらは編集しないでください）
  username: root
  password: <%= ENV['DATABASE_PASSWORD'] %>
  socket: /var/lib/mysql/mysql.sock

```

編集してコミットプッシュ
本番環境にいきます
作業ディレクトリをアプリにして、

```terminal:/var/www/アプリ
$ git pull origin master

$ rails db:create RAILS_ENV=production

$ rails db:migrate RAILS_ENV=production

$ rails assets:precompile RAILS_ENV=production
```

データベースを作成しました

```terminal:/var/www/アプリ
$ bundle exec unicorn_rails -c config/unicorn.rb -E production -D
# もしくは、
$ RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -D
```
これで http://＜サーバに紐付けたElastic IP＞:3000/で公開されているはずです

【追記】
assets:precompileしたら「yarnをインストールしてください」とでてエラーが出続けてしまったので
その時の対処法を追記します

```terminal:EC2インスタンス
$ yum -y install wget
$ curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
$ sudo yum install yarn
$ yarn -v
# ↑でバージョン確認できたら成功、$ rails assets:precompile RAILS_ENV=productionから続けてください
```