Dragon Arrow written by Tatsuya Nakaji, all rights reserved animated-dragon-image-0164

EC2内にRails5.2 + unicorn(アプリケーションサーバ) + Nginx(Webサーバ) を導入

updated on 2019-07-08

イメージ

前提: ruby, データベースのユーザー作成済み、gitの連携が終わっていて、 AWSで公開する最終段階にいることを想定


初めに: 

  • Webサーバは、HTTPに則り、クライアントソフトウェアのウェブブラウザに対して、HTMLやオブジェクト(画像など)の表示を提供するサービスプログラム及び、サーバコンピュータを指す (wikipedia)
  • アプリケーションサーバは、ビジネスロジックなどを実装したアプリケーションソフトウェアを実行することを専門とするコンピュータネットワーク上のサーバコンピュータ、もしくはそのようなコンピュータ上でのアプリケーションの実行を管理補助するミドルウェアのこと。クライアントからのHTTPのレスポンス要求を処理するウェブサーバとバックエンドのデータベース中核層への橋渡しを担い、データの加工などの処理を行う。 (wikipedia)

(https://www.draw.io/ で上記画像を作成しました。面白いので使ってみてね)

ちなみに、rails s のコマンドを打ち込んで起動するサーバー(WEBrick)は、アプリケーションサーバーです。

大半のアプリケーションサーバーは、webサーバーを使わずに単体で実行できます。
(本番環境ではwebサーバーを設置することがほとんどですが)



手順1. Unicornの設定

Unicornとはアプリケーションサーバーの一種です。
[tatsuya@ip-10-0-0-238 ~] $: vi Gemfile
-----------------------------
#以下を追記
group :production, :staging do
    gem 'unicorn'
end
----------------------------
[tatsuya@ip-10-0-0-238 ~] $ gem install bundler
[tatsuya@ip-10-0-0-238 ~] $ bundle install
[tatsuya@ip-10-0-0-238 ~] $ vi config/unicorn.conf.rb
----------------------------

viコマンドでconfig配下に生成したunicornの設定ファイルに、下記を記述します。

unicorn.conf.rb

  # set lets
  $worker  = 2
  $timeout = 30
  $app_dir = "/var/www/rails/myapp" #自分のアプリケーション名
  $listen  = File.expand_path 'tmp/sockets/unicorn.sock', $app_dir
  $pid     = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
  $std_log = File.expand_path 'log/unicorn.log', $app_dir
  # set config
  worker_processes  $worker
  working_directory $app_dir
  stderr_path $std_log
  stdout_path $std_log
  timeout $timeout
  listen  $listen
  pid $pid
  # loading booster
  preload_app true
  # before starting processes
  before_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
    old_pid = "#{server.config[:pid]}.oldbin"
    if old_pid != server.pid
      begin
        Process.kill "QUIT", File.read(old_pid).to_i
      rescue Errno::ENOENT, Errno::ESRCH
      end
    end
  end
  # after finishing processes
  after_fork do |server, worker|
    defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
  end

これでUnicornの設定が完了です。


手順2. Nginxの設定

NginxはWebサーバーにあたります。

[tatsuya@ip-10-0-0-238 ~] sudo yum install nginx
[tatsuya@ip-10-0-0-238 ~]$ cd /etc/nginx/conf.d/
[tatsuya|conf.d]$ sudo vi myapp.conf #自分のアプリケーション名でファイル名変更

viコマンドで作成したnginxの設定ファイルには、下記を記述します。


myapp.conf(アプリ名.conf)

# log directory
error_log  /var/www/rails/myapp/log/nginx.error.log; #自分のアプリケーション名に変更
access_log /var/www/rails/myapp/log/nginx.access.log; #自分のアプリケーション名に変更
# max body size
client_max_body_size 2G;
upstream app_server {
  # for UNIX domain socket setups
  server unix:/var/www/rails/myapp/tmp/sockets/unicorn.sock fail_timeout=0; #自分のアプリケーション名に変更
}
server {
  listen 80;
  server_name ~~~.~~~.~~~.~~~;(#アプリのElastic IPに変更してください)
  # nginx so increasing this is generally safe...
  keepalive_timeout 5;
  # path for static files
  root /var/www/rails/myapp/public; #自分のアプリケーション名に変更
  # page cache loading
  try_files $uri/index.html $uri.html $uri @app;
  location @app {
    # HTTP headers
    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;
  }
  # Rails error pages
  error_page 500 502 503 504 /500.html;
  location = /500.html {
    root /var/www/rails/myapp/public; #自分のアプリケーション名に変更
  }
}


下記のファイルで読み込まれます。なお下記のファイルはデフォルトのままにしておきます。

etc/nginx/nginx.conf

# for more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
  worker_connections 1024;
}

http {
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log  /var/log/nginx/access.log  main;

sendfile            on;
tcp_nopush          on;
tcp_nodelay         on;
keepalive_timeout   65;
types_hash_max_size 2048;

include             /etc/nginx/mime.types;
default_type        application/octet-stream;

# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;

server {
listen       80 default_server;
listen       [::]:80 default_server;
server_name  _;
root         /usr/share/nginx/html;

# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;

location / {
}

error_page 404 /404.html;
location = /40x.html {
}

error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}

# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }

}


設定ファイルの記述が終わったら、下記も実行してください。やらないと画像のアップロード等のファイル送信系はPermission deniedになります

[tatsuya|conf.d] cd /var/lib
[tatsuya|lib] sudo chmod -R 775 nginx

MySQLの設定


続いてDBです。
(アプリケーションのDBがMySQLで作成されている前提で話を進めていきます。)

下記コマンドを打ち込み、MySQLに関する設定を変更していきましょう。

[tatsuya|myapp]$ vi config/database.yml
----------------------------
  production:
    <<: *default
    database: <%= Rails.application.credentials.db[:database] %>
    username: <%= Rails.application.credentials.db[:username] %>
    password: <%= Rails.application.credentials.db[:password] %>
    host: <%= Rails.application.credentials.db[:host] %> # RDSを使ってないので、とりあえずlocalhostを指定しています RDS使用者はエンドポイント
[tatsuya|myapp]$ EDITOR=vim bin/rails credentials:edit
db:
  database: xxxxx
  username: xxxxx
  password: xxxxx
  host: xxxxx
...
[tatsuya|myapp]$ sudo service mysqld start #mysqldの起動
[tatsuya|myapp]$ ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock
[tatsuya|myapp]$ rake db:create RAILS_ENV=production
[tatsuya|myapp]$ rake db:migrate RAILS_ENV=production

アプリのmigrationファイルが実行されたログが出て来れば無事成功です(権限が原因でmysqldの起動が出来ないことがあります。その場合はchownやchmodコマンドでmysql関連ファイルの権限を変更してあげましょう。)

Nginxの起動

Nginxを起動

[tatsuya|myapp]$ sudo service nginx start

http://xx.xx.xx.xx (Elastic IPアドレス) にアクセス

もし繋がらなかったらUnicornを再起動もしくは停止してたら起動させる

[myapp]$ ps -ef | grep unicorn | grep -v grep
tatsuya  xxxxx     1  0 05:19 ?        00:00:01 unicorn_rails master -c /var/www/rails/myapp/config/unicorn.conf.rb -D -E production
tatsuya  yyyyy xxxxx  0 05:19 ?        00:00:00 unicorn_rails worker[0] -c /var/www/rails/myapp/config/unicorn.conf.rb -D -E production
tatsuya  zzzzz xxxxx  0 05:19 ?        00:00:00 unicorn_rails worker[1] -c /var/www/rails/myapp/config/unicorn.conf.rb -D -E production

こんな感じで3行表示されていれば既に起動されています。何も表示されなかったら起動してません

[起動方法]

[tatsuya]$ unicorn_rails -c /var/www/rails/myapp(アプリの名前)/config/unicorn.conf.rb -D -E production #unicornを起動させる

[再起動方法]

・一旦きる

[tatsuya]$ kill -9 xxxx # unicornプロセスをきる

・起動する

[tatsuya]$ unicorn_rails -c /var/www/rails/myapp(アプリの名前)/config/unicorn.conf.rb -D -E production #unicornを起動させる


Nginxもリロードさせます。

[tatsuya|myapp]$ sudo nginx -s reload


アクセスできれば完了

「このサイトにアクセスできません」となる人は本番環境設定でブロックしてしまっている可能性があります。ssl設定を確認しましょう

config/environments/production.rb

config.force_ssl = true
を
config.force_ssl = false
に変更(ssl証明書をまだ発行していない人はtrueだとアクセスできない)


勝手にhttpsにリダイレクトされてしまう人は

chromeにて

 閲覧履歴を消去->キャッシュされた画像ファイルを削除->データを削除
キャッシュを捨てることで,httpsに勝手に飛ばされていたのをhttpでアクセスできるようになる


セキュリティグループの許可について

インバウンド設定、アウトバウンド設定にてhttpの許可を出しておく


上記をきちんとやれていればアクセスできるはずです!

祝デプロイ!

完!!




d以下、サーバーでの多用コマンド(注意: 筆者のアプリ名はfroala-blogなので自分のアプリ名に読み替えてください)

・nginx

アクセスログ(アプリ接続)

sudo tail -f /var/www/rails/froala-blog/log/nginx.access.log

エラーログ(アプリ接続)

sudo tail -f /var/www/rails/froala-blog/log/nginx.error.log

アクセスログ(エンジン起動時)

sudo tail -f /var/log/nginx/access.log

エラーログ(エンジン起動時)

sudo tail -f /var/log/nginx/error.log

リロード

sudo nginx -s reload

スタート、ストップ、再起動

sudo service nginx start
sudo service nginx stop
sudo service nginx restart

プロセスのポートを調べる(nginxをstopできないときにプロセスをkillして再起動)

ps aux | grep nginx

ポートをきる

kill -9 xxxx

nginxの設定ファイル編集

sudo vi /etc/nginx/nginx.conf

アプリのnginxとの接続設定ファイル編集

sudo vi /etc/nginx/conf.d/froala-blog.conf


・unicorn

unicornログ

sudo tail -f /var/www/rails/froala-blog/log/unicorn.log

unicorn設定ファイル編集

vim /var/www/rails/froala-blog/config/unicorn.conf.rb

unicorn起動

bundle exec unicorn_rails -c /var/www/rails/froala-blog/config/unicorn.conf.rb -D -E production

プロセス確認

ps -ef | grep unicorn | grep -v grep

ポート確認

cat /var/www/rails/froala-blog/tmp/pids/unicorn.pid

停止(プロセス確認からポートを探ってkillしてもいいが以下だと一行で停止できる)

sudo kill -QUIT `cat /var/www/rails/froala-blog/tmp/pids/unicorn.pid`

起動

bundle exec unicorn_rails -c /var/www/rails/froala-blog/config/unicorn.conf.rb -D -E production

再起動

sudo kill -HUP `cat /var/www/rails/froala-blog/tmp/pids/unicorn.pid`



参考文献 https://qiita.com/naoki_mochizuki/items/5a1757d222806cbe0cd1