Rails4 & Unicorn & Nginx & EC2でサーバー構築


概要

EC2へデプロイし、とりあえず繋がるまでをまとめています。
Amazon Web Services上でEC2インスタンスの作成と、ローカルから作成されたEC2インスタンスにsshのログインまでが完了していることが前提です。

使用した環境

  • Rails 4.2.0
  • Ruby 2.2.0
  • rbenv 0.4.0
  • Unicorn 4.8.3
  • Nginx 1.6.2
  • MySQL 5.5.40
  • EC2 Amazon Linux AMI 2015.09.1 (HVM)(プロダクションマシン)
  • Git(リポジトリマシン)

1. ユーザーの作成

ユーザーをec2-userからrootに切り替えてパスワードを設定する。

$ sudo su -
$ passwd

- New password: に続けて新しいパスワードを設定する
- all authentication tokens updated successfully.と表示されればok

デフォルトのec2-user以外の作業用ユーザーを作成する。

$ useradd [任意の名前]
$ passwd [作成したユーザー名]

- New password: に続けて新しいパスワードを設定する
- all authentication tokens updated successfully.と表示されればok

作成した作業用ユーザーにsudo権限を与える。

$ usermod -G wheel [作成したユーザー名]
$ sudo visudo

- 以下のコメントアウトを外す
# %wheel ALL=(ALL) ALL

exitしてec2-userへ戻り作成した作業用ユーザーで入れるか確認する。
以降の作業は基本的に作業用ユーザーで行い、rootやec2-userでは作業しない。

$ su - [作成したユーザー名]

2. デプロイするディレクトリを作成

- 現在のディレクトリを確認
$ pwd
/home/[作成したユーザー名]

- デプロイは/var/www 配下に作成
$ cd /var
$ sudo mkdir www
$ cd www
$ sudo mkdir [あなたのアプリ名]
$ cd [あなたのアプリ名]
$ sudo chown [作成したユーザー名] [あなたのアプリ名]
$ sudo chgrp [作成したユーザー名] [あなたのアプリ名]

3. 必要なものを順番にインストール

これからインストールするものは必ずローカル環境のバージョンと合わせるようにする。

1)前準備

$ sudo yum update -y

$ sudo yum -y install gcc
$ sudo yum -y install make
$ sudo yum -y install gcc-c++
$ sudo yum -y install patch
$ sudo yum -y install bzip2
$ sudo yum -y install autoconf
$ sudo yum -y install automake
$ sudo yum -y install libtool
$ sudo yum -y install bison
$ sudo yum -y install readline-devel
$ sudo yum -y install libyaml-devel
$ sudo yum -y install libffi-devel
$ sudo yum -y install zlib-devel
$ sudo yum -y install httpd-devel
$ sudo yum -y install openssl-devel
$ sudo yum -y install curl-devel
$ sudo yum -y install sqlite-devel

- もしくは以下でも可能
$ sudo yum install -y gcc make gcc-c++ patch bzip2 autoconf automake libtool bison readline-devel libyaml-devel libffi-devel zlib-devel httpd-devel openssl-devel curl-devel sqlite-devel

2)MySQLのインストール

$ sudo yum install mysql-devel

- MySQL Serverをインストール
$ sudo yum install mysql-server

- MySQLの起動設定
$ sudo chkconfig mysqld on

- chkconfigコマンドで起動設定が成功しているかを確認することができる。
- 以下のように表示されれば設定が成功している。
$ chkconfig
mysqld           0:off   1:off   2:on    3:on    4:on    5:on    6:off

- MySQLを起動する。
$ sudo /etc/init.d/mysqld start

- もしくは以下でも同じ。
$ sudo service mysqld start

- rootでログインし新規ユーザーを作成する。
$ mysql -u root
mysql> GRANT ALL PRIVILEGES ON [データベース名].* TO [あなたのアプリ名]@localhost IDENTIFIED BY ‘[設定するパスワード]';

MySQLの文字コードがデフォルトでlatin1になっている場合があるので確認する。

mysql> SHOW VARIABLES LIKE 'character_set%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.00 sec)

- character_set_filesystem と character_sets_dir 以外が utf8 になっていればok。
- なっていなければutf8に統一し、再起動しておく。

mysql> set character_set_server = utf8;
Query OK, 0 rows affected (0.00 sec)

$ sudo service mysqld restart

3)gitのインストール

$ sudo yum install git

4)ruby-buildのインストール

$ git clone git://github.com/sstephenson/ruby-build.git
$ cd ruby-build
$ sudo ./install.sh

5)rbenvのインストール

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bashrc
$ exec $SHELL -l

- インストールしたrbenvバージョン確認
$ rbenv --version
rbenv 0.4.0-146-g7ad01b2

6)rubyのインストール

- インストール可能なバージョンを確認
$ rbenv install -l
(中略)
2.1.5
2.2.0-dev
2.2.0-preview1
2.2.0-preview2
2.2.0-rc1
2.2.0
2.2.0
2.3.0-dev
jruby-1.5.6
(中略)

$ rbenv install 2.2.0
$ rbenv global 2.2.0
$ rbenv rehash

- インストールしたRubyのバージョン確認
$ ruby -v
ruby 2.2.0 (2015-02-26 revision 49769) [x86_64-linux]

7)bundlerのインストール

$ sudo gem update --system
$ sudo gem install nokogiri
$ bundle list
-bash: bundle: コマンドが見つかりません
$ sudo gem install bundler
Fetching: bundler-1.6.3.gem (100%)
Successfully installed bundler-1.6.3
1 gem installed
$ gem list

*** LOCAL GEMS ***
bigdecimal (1.2.3)
bundler (1.6.3)
io-console (0.4.2)
json (1.8.1)
minitest (4.7.5)
nokogiri (1.6.7.2)
psych (2.0.2)
rake (10.1.0)
rdoc (4.1.0)
test-unit (2.1.0.0)
合計 0

nokogiriがinstallできない場合は以下の方法で入れる。

- rootで入り直して以下をyumでinstallする
# yum -y install libxml2 libxslt libxml2-devel libxslt-devel

- 作業ユーザーに戻り以下のコマンドでnokogiriをinstallする
$ gem install nokogiri -- --use-system-libraries

8)therubyracerのインストール

$ sudo gem install therubyracer

9)railsのインストール

$ sudo gem install rails -v 4.2.0

- インストールしたRailsのバージョンとgem確認
$ pwd /root
$ rails -v
Rails 4.2.0

10)railsアプリケーションを新規作成

$ cd /var/www
$ rails new [あなたのアプリ名]
$ cd [あなたのアプリ名]

11)unicornのインストール

$ sudo gem install unicorn

- configファイルを作成
$ cd [あなたのアプリ名]
$ sudo vi config/unicorn.rb
config/unicorn.rb
worker_processes 2

listen '/tmp/unicorn.sock'

stderr_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])
stdout_path File.expand_path('log/unicorn.log', ENV['RAILS_ROOT'])

preload_app true

before_fork do |server, worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!

  old_pid = "#{ server.config[:pid] }.oldbin"
  unless old_pid == server.pid
    begin
      Process.kill :QUIT, File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

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

12)nginxのインストール

$ sudo yum -y install nginx

- 起動確認
$ sudo /etc/init.d/nginx start

- http://xxx.compute.amazonaws.com/ にアクセス
- Welcome to nginx on the Amazon Linux AMI!と出れば成功

- nginxが起動できない場合は以下でログを確認
$ sudo tailf /var/log/nginx/error.log

- nginxを一旦停止
$ sudo /etc/init.d/nginx stop

13)nginxとunicornを紐付け

- nginxの設定ファイルを編集
$ sudo vi /etc/nginx/nginx.conf
/etc/nginx/nginx.conf
events {
  worker_connections 2048;
}

http {
  upstream unicorn {
    server unix:/tmp/unicorn.sock;
  }
  server {
    listen 80;
    server_name localhost;
    root /var/www/[あなたのアプリ名];
    error_log /var/www/[あなたのアプリ名]/log/nginx.log;
    include /etc/nginx/mime.types;
    location / {
      if (-f $request_filename) { break; }
      proxy_set_header X-Real-IP  $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_pass http://unicorn;
    }
  }
}

- upstream unicornの「unicorn」は、proxy_passのhttp://unicornの「unicorn」と合わせる必要がある。
- server unixは先ほど設定したunicorn.rbのlistenと合わせる必要がある。
- mime.typesをincludeしてあげないとproduction環境でstylesheetsが反映されない問題があるので気をつける。

14)nginx、unicornを起動

- nginxを起動
$ sudo /etc/init.d/nginx start

- unicornを起動
$ cd [あなたのアプリ名]
$ unicorn_rails -c config/unicorn.rb -D
$ unicorn_rails -E production -c config/unicorn.rb -D (本番環境で稼働させる場合)

- unicornが起動できない場合はログを確認
$ tailf log/unicorn.log

- プロセスを検索して起動確認
- unicorn masterが動いていればok
$ ps ax|grep unicorn|grep -v grep

4. 動作確認

http://xxx.compute.amazonaws.com/ にアクセスし

Railsのトップページが表示されればok。

画面が真っ白になりunicornを本番環境で稼働できない場合

ERROR -- : app error: Missing `secret_token` and `secret_key_base` for 'production' environment, set these values in `config/secrets.yml` (RuntimeError)

SECRET_KEY_BASEを設定していない場合に起きる。config/secrets.ymlファイルで「secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>」という部分が存在するため、下記コマンドを実施し、unicornを再起動する。

$ export SECRET_KEY_BASE=`rake secret`
$ killall unicorn_rails
$ unicorn_rails -E production -c config/unicorn.rb -D

5. 参考

AWSのEC2上でRails+Unicorn+Nginxを実現する
nginx + unicorn + Railsの設定方法 - Qiita
AmazonLinuxにrbenvでrubyを入れてみる · mechamogera/MyTips Wiki
ec2にrbenvをインストールする方法 - Hive Color
Nginx fails to load css files - Stack Overflow