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



## 概要
EC２へデプロイし、とりあえず繋がるまでをまとめています。
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を実現する](https://gist.github.com/honjo2/5023446)
・[nginx + unicorn + Railsの設定方法 - Qiita](http://qiita.com/akito1986/items/56198edcafc222b320a8)
・[AmazonLinuxにrbenvでrubyを入れてみる · mechamogera/MyTips Wiki](https://github.com/mechamogera/MyTips/wiki/AmazonLinux%E3%81%ABrbenv%E3%81%A7ruby%E3%82%92%E5%85%A5%E3%82%8C%E3%81%A6%E3%81%BF%E3%82%8B)
・[ec2にrbenvをインストールする方法 - Hive Color](http://hivecolor.com/id/129)
・[Nginx fails to load css files - Stack Overflow](http://stackoverflow.com/questions/10075304/nginx-fails-to-load-css-files)