【AWS】Ruby on Rails + Nginx + Unicorn + MySQL 環境構築

概要

AWS で初めて Rails のアプリを作成した時の手順をまとめました。

手順に沿って実行して頂ければ、Rails アプリの起動まで出来ると思います。

 

環境

こちらの環境でアプリケーションを作成しました。

サーバOS   Amazon Linux
Web サーバ   Nginx
Rack サーバ   Unicorn
データベース   MySQL
フレームワーク   Rails 5.0.X
プログラミング言語

  Ruby 2.4.X

 

タイムゾーンの設定

初めにタイムゾーンの設定を変更します。

Amazon Linux では、デフォルトのタイムゾーンが UTC (協定世界時間) に設定されています。

このままでは扱いづらいので、JST (日本標準時間) に変更します。

$ sudo vim /etc/sysconfig/clock
ZONE="Asia/Tokyo" # ZONE エントリを書き換えます
UTC=true          # 変更しないでください

$ sudo ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
$ sudo shutdown -r now

$ date
Tue Jul 25 21:57:06 JST 2017 # JST に変更されています

参考:Linux インスタンスの時刻の設定 - Amazon Elastic Compute Cloud

 

ロケールの設定

次にロケールの設定を行います。

基本的に UTF-8 に変更しようと思います。

$ sudo vim /etc/sysconfig/i18n
LANG=ja_JP.UTF-8
LC_CTYPE=ja_JP.UTF-8
LC_NUMERIC=ja_JP.UTF-8
LC_TIME=ja_JP.UTF-8
LC_COLLATE=ja_JP.UTF-8
LC_MONETARY=ja_JP.UTF-8
LC_MESSAGES=ja_JP.UTF-8
LC_PAPER=ja_JP.UTF-8
LC_NAME=ja_JP.UTF-8
LC_ADDRESS=ja_JP.UTF-8
LC_TELEPHONE=ja_JP.UTF-8
LC_MEASUREMENT=ja_JP.UTF-8
LC_IDENTIFICATION=ja_JP.UTF-8

先ほどと date コマンドを実行してみると、日本語表記になりました。

$ date
2017年  7月 25日 火曜日 21:58:56 JST

参考:ロケールとは - 国際化対応言語環境の利用ガイド

 

Yum インストール

標準ライブラリ

$ sudo yum install gcc-c++ glibc-headers openssl-devel readline libyaml-devel readline-devel zlib zlib-devel

Git インストール

$ sudo yum install git

MySQL インストール

$ sudo yum install mysql mysql-devel

Nginx インストール

$ sudo yum install nginx

 

Ruby インストール

現在の Ruby の Version を確認します。

(※ デフォルトで Ruby が入っていない環境もあると思います。)

$ ruby -v
ruby 2.0.0p648 (2015-12-16) [x86_64-linux]

Rails 5.0.0 以上は Ruby 2.2.2 以上が必要となります。

Rails 5.0.0 以上を使いたいので、Ruby の Version を 2.4.0 にアップデートします。

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

$ rbenv install -v 2.4.0
$ rbenv rehash
$ rbenv global 2.4.0
$ ruby -v
ruby 2.4.0p0 (2016-12-24 revision 57164) [x86_64-linux]

参考

 

Bundler インストール

gem を使って Rails をインストールするので、先に gem 同士の互換性を管理してくれる bundler をインストールします。

$ gem install bundler

 

Rails インストール

Rails 5.0.X 系の最新バージョンをインストールします

$ gem install --no-ri --no-rdoc rails --version="~>5.0.0"
$ rails -v
Rails 5.0.4

 

Rails アプリ作成

hogehoge アプリケーションを作成します。

# 作業用ディレクトリ確保します
$ sudo mkdir /var/workspace
$ sudo chown ec2-user /var/workspace
$ cd /var/workspace

# データベースは MySQL を指定します
# Gemfile を修正したいので、この段階では bundle install を skip します
$ rails new hogehoge -d mysql --skip-test --skip-bundle

# 作成したアプリケーションに移動してください
$ cd hogehoge

Gemfile を修正

Rails では アプリケーションで利用したい gem パッケージを管理した、Gemfile というものがあります。

この Gemfile に unicorn の設定を追加してインストールする必要があります。

ちなみに、Javascript を利用するために必要なので、therubyracer も追加してください。(既に Gemfile に記載されているので、コメントアウトを外すだけでもいいです。)

# この 2 行を Gemfile に追加してください
$ vim Gemfile
gem 'unicorn', '~> 5.3'
gem 'therubyracer', platforms: :ruby

# Gemfile に書かれた gem パッケージと、その依存パッケージをインストールします
$ bundle install --path vendor/bundle

Nginx の設定

3 箇所ほど修正点があります。

$ sudo vim /etc/nginx/nginx.conf
user ec2-user; # user 変更
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;

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;

    include /etc/nginx/conf.d/*.conf;

    index   index.html index.htm;
    
   # unicornapp 追加
    upstream unicornapp {
        server unix:/var/workspace/hogehoge/tmp/unicorn.sock;
    }
    server {
        listen       80 default_server;
        listen       [::]:80 default_server;
        server_name  localhost;
        root         /usr/share/nginx/html;

        include /etc/nginx/default.d/*.conf;

        location / {
            proxy_pass http://unicornapp; # proxy_pass 追加
        }

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

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

設定ファイルを更新したら、Nginx を再起動します

$ sudo service nginx restart
nginx を停止中:                                            [  OK  ]
nginx を起動中:                                            [  OK  ]

 EC2 ダッシュボードに戻って、セキュリティグループにインターネットからの HTTP アクセス許可のルールを追加してください。

f:id:kyamanak83:20170725235134p:plain

ここまで完了すると、インスタンスのパブリックDNS、又はパブリック IP にブラウザからアクセスした時、Nginx のエラー画面が見れるはずです。

 

f:id:kyamanak83:20170726223713p:plain

データベース接続の設定

Rails アプリケーションで利用する、データベースとの接続設定を行います。

データベースは既にRDSインスタンスに用意してあるものとして話を進めます。

$ vim config/database.yml
default: &default
 adapter: mysql2
 encoding: utf8
 pool: 5
 port: 3306
 username:  # ユーザ名
 password:  # パスワード
development:
 <<: *default
 host: # ホスト名
 database: # データベース名

RDS ダッシュボードに戻って、セキュリティグループに、データベースに接続したい EC2 インスタンスのプライベート IP を追加してください。

f:id:kyamanak83:20170726225648p:plain

Unicorn の設定

最後に Rails アプリケーションの画面を表示するために、Unicorn の設定を行います。

Google で検索すると色んな人の設定が出てくると思います。

自分は下記のように設定しました。(自分も Google 検索で誰かのをパクりました^^;)

新しく config/unicorn.rb ファイルを作成します。

$ vim config/unicorn.rb
rails_root = File.expand_path('../../', __FILE__)

worker_processes 2

working_directory rails_root
timeout 30
preload_app true

# unicorn.sock ファイルの PATH を変更する場合は nginx.conf の修正も必要です
listen "#{rails_root}/tmp/unicorn.sock"
pid "#{rails_root}/tmp/unicorn.pid"

stderr_path File.expand_path('../../log/unicorn_stderr.log', __FILE__)
stdout_path File.expand_path('../../log/unicorn_stdout.log', __FILE__)

preload_app true

before_fork do |server, worker|
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU
      puts "Sending #{sig} signal to old unicorn master..."
      Process.kill(sig, File.read(old_pid).to_i)
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end

  sleep 1
end

after_fork do |server, worker|
  ActiveRecord::Base.establish_connection if defined?(ActiveRecord::Base)
end

Unicorn を起動させます

$ bundle exec unicorn -c config/unicorn.rb -E development -D

 

最後に

ここまで完了すると Rails の画面が表示されると思います。

 

f:id:kyamanak83:20170726225834p:plain

おしまい。