いわりょのBlog

IT関連で学んだことを書いていきます。

自作railsアプリをデプロイする Part10 EC2インスタンス環境構築編

前回やったところから残りの設定を終わらせていきたいと思います。

f:id:Ryo10Leo:20200114142606p:plain

前回は大まかに、インスタンスに諸々の設定をしたあとアプリのクローンを作成したところまでいきました。

今回はWebサーバーやアプリケーションサーバー、SQLなどの設定をやっていきます。

正直一番緊張する内容です。。。

構築する環境を理解する

今回作る環境は一言でいうと「Web3層構成」です。それらは以下の3つの層で成り立っています。

Webサーバ層

Webブラウザからのアクセス要求を処理する層を示します。必要に応じて、Webアプリケーション層へリクエストを要求します。

ウェブアプリケーション

Webサーバから受けたリクエストをもとに、バックエンドで動作するJavaphpRubyなどを実行したり、データベースへのアクセスを行ない、処理を行ないます。

データベース層

入力したデータや、アプリケーションで参照するデータを保管する役割を持ちます。

参考 ↓
アプリケーションサーバってなに?Webサーバとの違い | 構築ツールの最新情報や基礎知識 | 知る・学ぶ | Marketing Bank (マーケティングバンク)

よってそれぞれの層の役割を担うのに必要なソフトウェアをインストールしていき、それらを関連づけることで「Web3層構成」を構築していきます。

構築するものを図で理解する

EC2インスタンス内に以下の環境を構築していきます。

f:id:Ryo10Leo:20200115230205p:plain

Webサーバ層に「Nginx」、ウェブアプリケーション層に「Puma」、データベース層には「PostgerSQL」使います。

図のアプリケーションサーバーのpumaに関しては、railsアプリケーションを動かすために必要なものです。

さらにアプリケーションサーバーには「Rack」と呼ばれるWebサーバーからのリクエストを翻訳してRailsに伝える(その逆も)という仕組みがあります。

よって以下のような流れでリクエストから処理(処理からレスポンス)の流れが実現できます。

ちなみにNginx と Puma間の情報のやりとりは、「UNIX Socket」を使います。

f:id:Ryo10Leo:20200115232251p:plain

アプリケーションサーバーの設定(Puma)

Railsにはデフォルトでpumaが入っているので、いろいろ設定していきます。
本番環境での操作であることに注意してください。

[ryo|~]$ cd /var/www/rails/myapp

先にバンドラーを取得。

[ryo|~ myapp $ gem install bundler

Pumaとpuma_worker_killerと他のGemfileに記載されているgemをインストールしていきます。

puma_worker_killerはpumaのパフォーマンスを管理して、ケアするものと思ってください。

Gemfile

・
・
gem 'puma',         
・
・
group :production do
 (省略)
  gem 'puma_worker_killer'
end
[ryo|~ myapp $ bundle install --without development test

設定ファイルを作成します。

[ryo|~ myapp]$ touch config/puma/production.rb
[ryo|~ myapp]$ touch tmp/sockets/puma.sock
[ryo|~ myapp]$ touch tmp/pids/puma.pid

puma.sockとpuma.pidは空で大丈夫です。

production.rbに以下を追記↓

# config/puma/production.rb

# UNIX Socketへのバインド
tmp_path = "#{File.expand_path("../../..", __FILE__)}/tmp"
bind "unix://#{tmp_path}/sockets/puma.sock"

# スレッド数とWorker数の指定
threads 3, 3
workers 2
preload_app!

# デーモン化の設定
daemonize
pidfile "#{tmp_path}/pids/puma.pid"
stdout_redirect "#{tmp_path}/logs/puma.stdout.log", "#{tmp_path}/logs/puma.stderr.log", true

# rails restartコマンドが使えます。
plugin :tmp_restart

# puma_worker_killerの設定
before_fork do
  PumaWorkerKiller.config do |config|
    # 閾値を超えた場合にkillする
    config.ram           = 1024 # mb
    config.frequency     = 5 * 60 # per 5minute
    config.percent_usage = 0.9 # 90%
    # 閾値を超えたかどうかに関わらず定期的にkillする
    config.rolling_restart_frequency = 24 * 3600 # per 1day 
    # workerをkillしたことをログに残す
    config.reaper_status_logs = true
  end
  PumaWorkerKiller.start
  ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord)
end
on_worker_boot do
  ActiveRecord::Base.establish_connection if defined?(ActiveRecord)
end

Pumaの設定は終わりです。
この時点でrails sしても動きませんでした。
理由としてはデータベースをrailsアプリと接続してなかったので、「PostgreSQL」をrailsをつなげていきます。

データベースの設定

データベース側の設定は以下の記事の通り↓
ryo10leo.hatenablog.com

まずdatabase.ymlを編集

config/database.yml
・
・
・
production:
  <<: *default
  adapter: postgresql
  database: myapp_production
  user: <%= ENV['RAILS_DATABASE_USERNAME'] %>
  password: <%= ENV['RAILS_DATABASE_PASSWORD'] %>
  encoding: utf8

userとパスワードは環境変数にしたのでそれぞれ設定します。

[ryo|~ myapp]$ rails db:create RAILS_ENV=production
[ryo|~ myapp]$ rails db:migrate RAILS_ENV=production
#seed.rbがあるなら↓
[ryo|~ myapp]$ rails db:seed RAILS_ENV=production

これで

[ryo|~ myapp]$ rails s -e production

でpumaが起動します。

Nginxサーバーインストールと設定

まずはNginxをインストール

[ryo|~ myapp]$ sudo yum install -y nginx

インスタンス再起動時の自動起動設定

[ryo|~ myapp]$ systemctl enable nginx

nginxの設定ファイルを作成します。↓

[ryo|~ myapp]$ cd ~
[ryo|~ ]$ touch  /etc/nginx/conf.d/myapp.conf

作成したファイルを編集します。

upstream <app_server> {
    server unix:///var/www/rails/<myapp>/tmp/sockets/puma.sock;
}

server {
    client_max_body_size 20M;
    listen       80;
    server_name  #取得したElastic IPアドレス;
    root /var/www/rails/<myapp>/public;

    location / {
        proxy_pass http://<app_server>;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_redirect off;
        proxy_connect_timeout 30;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root /var/www/rails/<myapp>/public;
    }
}

<myapp>は自分のアプリファイル、<app_server>は任意の値を設定します。
server_nameには自身で取得したElastic IPアドレスを書きます。

nginxを起動します。

[ryo|~ myapp]$ sudo service nginx start

これで大まかな設定は完了です!

しかし、これで起動したってわけではありませんでした。

多分ここから人それぞれいくつかのエラーに遭遇するはずです。

自分は一つ一つ調べれば、解決できるものが多かったので落ち着いてデバックすればアプリケーションが動くようになるので、勉強だと思って頑張りましょう。

自分は以下のような内容のエラーが起こりました。↓

Rails5をproduction(本番環境)で起動する時に嵌ったこと - Qiita

Rails4+nginxでfavicon.icoが正常に表示されない問題 - プログラマーになりたい

【初心者・独学者向け】Ruby on Railsのアプリを本番環境へデプロイした時に、CSSが反映されない場合の対処法 - Ruby on Rails | ゼロイチ | 独学者・初心者向けプログラミング・SEO入門サイト


表示はされたけどrails側のエラーでアプリが表示されない↓

【rails】本番環境でもエラー文を表示させる - Qiita


あとはインスタンス側で環境変数がうまく設定されてなかったとか、地味なことも探って行けば大丈夫です。

長かったなー

次は番外編などを書いていきたいです。