Rails3.2.8環境構築(Nginx+Unicorn)

Rubyインストール

apt-get update
apt-get install libssl-dev libreadline-dev libyaml-dev libxslt-dev gcc make

cd /usr/local/src
wget -c ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p286.tar.gz
tar zxvf ruby-1.9.3-p286.tar.gz
cd ruby-1.9.3-p286
./configure
make && make install

Railsインストール

apt-get install g++ curl libcurl4-openssl-dev
gem install rails

Nginxインストール

apt-get install libpcre3 libpcre3-dev

groupadd -g 2001 nginx
useradd -u 2001 -g nginx -s `which nologin` -d /usr/local/nginx nginx

cd /usr/local/src
wget -c http://nginx.org/download/nginx-1.2.4.tar.gz
tar zxvf nginx-1.2.4.tar.gz
cd nginx-1.2.4
./configure --prefix=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
make && make install

VirtualHost用ディレクトリ作成

mkdir /usr/local/nginx/conf/conf.d
mkdir /usr/local/nginx/vhosts

Nginx設定

cd /usr/local/nginx/conf
mv -i nginx.conf{,.`date +%Y%m%d`}
vi nginx.conf
user nginx nginx;
worker_processes 3;
worker_priority 0;
worker_rlimit_nofile 8192;

error_log  logs/error.log  notice;
pid logs/nginx.pid;

events {
    multi_accept off;
    worker_connections  1024;
    use epoll;
}

http {
    include mime.types;
    default_type application/octet-stream;

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

    sendfile on;
    server_tokens off;
    keepalive_timeout 10;
    index index.py index.wsgi index.php index.pl index.cgi index.html;
    error_page 500 502 503 504 /50x.html;

    server {
        listen 80 default;
        server_name _;
        root html;
        access_log logs/access.log main;

        location = /nginx_status {
                stub_status on;
                access_log off;
                allow 127.0.0.1;
                deny all;
        }
    }

    include conf.d/*.conf;
}

Nginx起動スクリプト作成

touch /etc/init.d/nginx
chmod 755 /etc/init.d/nginx
vi /etc/init.d/nginx
#!/bin/bash
 
# Nginx start stop script
#
# Debian
### BEGIN INIT INFO
# Provides:          nginx
# Required-Start:    $all
# Required-Stop:     $all
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: start and stop Nginx daemon
# Description:       start and stop Nginx daemon
### END INIT INFO
#
# CentOS
# chkconfig: 345 99 1
# description: Nginx start stop script
# processname: nginx
 
SERVER_ROOT=/usr/local/nginx
NGINX=$SERVER_ROOT/sbin/nginx
PIDFILE=$SERVER_ROOT/logs/nginx.pid
 
[ -x $NGINX ] || exit 1
 
if ! $NGINX -t > /dev/null 2>&1 ; then
    echo "Syntax error! Please confirm the config file."
    exit 1
fi
 
do_start() {
    if [ -f $PIDFILE ] ; then
        if ps -p `cat $PIDFILE` > /dev/null 2>&1 ; then
            echo "Nginx is already running..."
            exit 1
        fi
    fi
    $NGINX || echo "Failed to start Nginx."
}
 
do_stop() {
    if [ ! -f $PIDFILE ] ; then
        echo "Nginx is not running."
        exit 1
    fi
    if ps -p `cat $PIDFILE` > /dev/null 2>&1 ; then
        kill -QUIT `cat $PIDFILE` || echo "Failed to stop Nginx."
    else
        echo "Nginx is not running."
        exit 1
    fi
}
 
do_graceful() {
    if [ ! -f $PIDFILE ] ; then
        echo "Nginx is not running."
        exit 1
    fi
    if ps -p `cat $PIDFILE` > /dev/null 2>&1 ; then
        kill -HUP `cat $PIDFILE` || echo "Failed to graceful Nginx."
    else
        echo "Nginx is not running."
        exit 1
    fi
}
 
case $1 in
    start)
        do_start;;
    stop)
        do_stop;;
    restart)
        do_stop
        sleep 2
        do_start;;
    graceful)
        do_graceful;;
    *)
        echo "Usage: nginx [start|stop|restart|graceful]"
        exit 1;;
esac
 
exit 0

Nginx起動と自動起動設定

/usr/local/nginx/sbin/nginx -t
/etc/init.d/nginx start
update-rc.d nginx defaults

MySQLインストール

groupadd -g 2008 mysql
useradd -u 2008 -g mysql -d /home/mysql -m -s /bin/bash mysql

apt-get install mysql-server mysql-client libmysqlclient-dev

MySQL設定

vi /etc/mysql/my.cnf
[mysqld]
# 追記
character-set-server = utf8
skip-character-set-client-handshake
collation-server = utf8_general_ci
init-connect = SET NAMES utf8

[mysql]
# 追記
default-character-set = utf8

MySQL再起動と初期設定

/etc/init.d/mysql restart
mysql_secure_installation

DBとユーザの作成

# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 42
Server version: 5.5.24-0ubuntu0.12.04.1 (Ubuntu)

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database rails;
Query OK, 1 row affected (0.01 sec)

mysql> create database rails_development;
Query OK, 1 row affected (0.00 sec)

mysql> create database rails_test;
Query OK, 1 row affected (0.00 sec)

mysql> grant all privileges on rails.* to rails@localhost identified by 'secret';
Query OK, 0 rows affected (0.00 sec)

mysql> grant all privileges on rails_development.* to developer@localhost identified by 'secret';
Query OK, 0 rows affected (0.01 sec)

mysql> grant all privileges on rails_test.* to tester@localhost identified by 'secret';Query OK, 0 rows affected (0.00 sec)

mysql> quit
Bye

Railsプロジェクト作成

mkdir -p /usr/local/rails
cd /usr/local/rails
rails new myapp --skip-bundle --database=mysql

ライブラリインストール

cd myapp
vi Gemfile
# 以下のコメントイン
gem 'therubyracer', :platforms => :ruby
gem 'unicorn'
bundle install --path vendor/bundle

DB接続設定

vi config/database.yml
development:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: rails_development
  pool: 5
  username: developer
  password: secret
  host: localhost
  port: 3306

test:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: rails_test
  pool: 5
  username: tester
  password: secret
  host: localhost
  port: 3306

production:
  adapter: mysql2
  encoding: utf8
  reconnect: false
  database: rails
  pool: 5
  username: rails
  password: secret
  host: localhost
  port: 3306

Unicorn設定

vi config/unicorn.rb
listen "/usr/local/rails/myapp/tmp/unicorn.sock" # by default Unicorn listens on port 8080
worker_processes 2 # this should be >= nr_cpus
pid "/usr/local/rails/myapp/log/unicorn.pid"
stderr_path "/usr/local/rails/myapp/log/unicorn.log"
stdout_path "/usr/local/rails/myapp/log/unicorn.log"

Unicorn起動スクリプト作成

touch script/unicorn.sh
chmod 755 script/unicorn.sh
vi script/unicorn.sh
#!/bin/sh
 
set -e
 
TIMEOUT=${TIMEOUT-60}
APP_ROOT=/usr/local/rails/myapp
PID=$APP_ROOT/log/unicorn.pid
#RAILS_ENV=production
RAILS_ENV=development
CMD="bundle exec unicorn -D -c $APP_ROOT/config/unicorn.rb -E $RAILS_ENV"
action="$1"
set -u
 
old_pid="$PID.oldbin"
 
cd $APP_ROOT || exit 1
 
sig () {
    test -s "$PID" && kill -$1 `cat $PID`
}
 
oldsig () {
    test -s $old_pid && kill -$1 `cat $old_pid`
}
 
case $action in
start)
    sig 0 && echo >&2 "Already running" && exit 0
    $CMD
    ;;
stop)
    sig QUIT && exit 0
    echo >&2 "Not running"
    ;;
force-stop)
    sig TERM && exit 0
    echo >&2 "Not running"
    ;;
restart|reload)
    sig HUP && echo reloaded OK && exit 0
    echo >&2 "Couldn't reload, starting '$CMD' instead"
    $CMD
    ;;
upgrade)
    if sig USR2 && sleep 2 && sig 0 && oldsig QUIT
    then
        n=$TIMEOUT
        while test -s $old_pid && test $n -ge 0
        do
            printf '.' && sleep 1 && n=$(( $n - 1 ))
        done
        echo
 
        if test $n -lt 0 && test -s $old_pid
        then
            echo >&2 "$old_pid still exists after $TIMEOUT seconds"
            exit 1
        fi
        exit 0
    fi
    echo >&2 "Couldn't upgrade, starting '$CMD' instead"
    $CMD
    ;;
reopen-logs)
    sig USR1
    ;;
*)
    echo >&2 "Usage: $0 <start|stop|restart|upgrade|force-stop|reopen-logs>"
    exit 1
    ;;
esac

VirtualHost設定

mkdir -p /usr/local/nginx/vhosts/xxx.com/logs
vi /usr/local/nginx/conf/conf.d/rails.conf
upstream backend-unicorn {
    server unix:/usr/local/rails/myapp/tmp/unicorn.sock;
}

server {
    listen 80;
    server_name xxx.com;
    root /usr/local/rails/myapp/public;
    index index.html index.htm;

    access_log /usr/local/nginx/vhosts/xxx.com/logs/access.log main;
    error_log /usr/local/nginx/vhosts/xxx.com/logs/error.log info;

    location / {
        try_files $uri @proxy_to_rails;
    }

    location @proxy_to_rails {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect off;
        proxy_pass http://backend-unicorn;
    }
}

Nginx再起動とUnicorn起動

/usr/local/nginx/sbin/nginx -t
/usr/local/nginx/sbin/nginx -s stop
/usr/local/nginx/sbin/nginx
./script/unicorn.sh start