k-yamadaのブログ

プログラミングのメモ

UbuntuにNginx + rails3 + unicorn + sslの環境を作る

Nginx

Nginxインストールの前提条件として必要なライブラリをインストールする

$ sudo apt-get install gcc libpcre3 libpcre3-dev zlib1g zlib1g-dev openssl libssl-dev -y

Nginxのダウンロード

最新の安定(stable)バージョンである1.2.3をインストールします。
最新バージョンは以下のサイトで確認してください
http://nginx.org/

$ cd
$ sudo wget http://nginx.org/download/nginx-1.2.3.tar.gz
$ sudo tar zxf nginx-1.2.3.tar.gz 
$ cd nginx-1.2.3/
$ sudo ./configure --prefix=/usr/local/nginx-1.2.3 --user=www-data --group=www-data --with-http_ssl_module --with-http_realip_module
$ sudo make
$ sudo make install
$ sudo ln -s /usr/local/nginx-1.2.3 /usr/local/nginx

オプションの説明

prefix prefixオプションではnginxをインストールするディレクトリを指定します(デフォルトは/usr/local/nginx)。Nginxを継続的にアップグレードさせるつもりがあるなら、バージョンごとに異なるprefixを指定するのがよい方法です。nginxインストール後、/usr/local/nginx-1.2.3を指す/usr/local/nginxというシンボリックリンクを作ります。nginxをアップグレードしたらシンボリックリンクを/usr/local/nginx-newver.versionを指すように変更します。
with-http_ssl_module HTTPSコンテンツに対応するために必要。(HTTPSはデフォルトで無効になっています)
with-http_realip_module Nginxをバックエンドサーバとして実行しているときに、ユーザのIPアドレスを取得するために必要

Nginxのシステムサービス化

/etc/init.d/nginxにinitスクリプトを作成します

/etc/init.d/nginx

#! /bin/sh
# Author: Ryan Norbauer http://norbauerinc.com
# Modified: Geoffrey Grosenbach http://topfunky.com
# Modified: Clement NEDELCU
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="nginx daemon"
NAME=nginx
DAEMON=/usr/local/nginx/sbin/$NAME
SCRIPTNAME=/etc/init.d/$NAME

# デーモンファイルが見つからなければ、スクリプトを終了する
test -x $DAEMON || exit 0

d_start() {
  $DAEMON || echo -n " already running"
}

d_stop() {
  $DAEMON -s quit || echo -n " not running"
}

d_reload() {
  $DAEMON -s reload || echo -n " could not reload"
}

case "$1" in
  start)
    echo -n "Starting $DESC: $NAME"
    d_start
    echo "."
  ;;
  stop)
    echo -n "Stopping $DESC: $NAME"
    d_stop
    echo "."
  ;;
  reload)
    echo -n "Reloading $DESC: configuration..."
    d_reload
    echo "reloaded."
  ;;
  restart)
    echo -n "Restarting $DESC: $NAME"
    d_stop
    # 再起動の前に2秒スリープする。Nginxデーモンが穏便に終了するための時間を与えるのである。
    sleep 2
    d_start
    echo "."
  ;;
  *)
    echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&2
    exit 3
  ;;
esac

exit 0

スクリプトに実行権限を与えます

$ sudo chmod +x /etc/init.d/nginx

これで、service nginx startを使ってサービスを起動出来るようになります。

$ sudo service nginx start
Starting nginx daemon: nginx.

次に、適切なランレベルに達したときにスクリプトが自動的に実行されるようにします

$ sudo update-rc.d -f nginx defaults

これで、リブート・シャットダウンランレベルではstopが実行され、他の全てのランレベルではstartが実行されるようになります。


Rails3 + unicorn環境の構築

Railsアプリを新規作成

$ rails new unicorn_sample
$ sudo ln -s ~/unicorn_sample /var/www/unicorn_sample
$ cd unicorn_sample
$ vim Gemfile
gem 'unicorn' # 追加
$ bundle install

unicornの設定ファイル作成

$ vim config/unicorn.rb

unicorn_sample/config/unicorn.rb

pid    'tmp/pids/unicorn.pid'
listen '/tmp/unicorn_sample.sock' # nginxとUNIXソケット経由で接続する
worker_processes 5
timeout 20

nginxの設定ファイル作成

$ mkdir config/nginx
$ vim config/nginx/nginx.conf

unicorn_sample/config/nginx/nginx.conf

worker_processes 1;
user nobody nogroup; # for systems with a "nogroup"
pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;

events {
  worker_connections 1024; # increase if you have lots of clients
  accept_mutex off; # "on" if nginx worker_processes > 1
}

http {
  include mime.types;
  default_type application/octet-stream;
  access_log /tmp/nginx.access.log combined;
  sendfile on;
  tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
  tcp_nodelay off; # on may be better for some Comet/long-poll stuff
  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 500;
  gzip_disable "MSIE [1-6]\.";
  upstream app_server {
    # for UNIX domain socket setups:
    server unix:/tmp/unicorn_sample.sock fail_timeout=0;
  }

  server {
    client_max_body_size 4G;
    server_name _;
    keepalive_timeout 5;

    # path for static files
    root /var/www/unicorn_sample/public;

    try_files $uri/index.html $uri.html $uri @app;

    location @app {
      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/unicorn_sample/public;
    }
  }
}
$ sudo ln -s ~/unicorn_sample/config/nginx/nginx.conf /usr/local/nginx/conf/nginx.conf

unicornRailsを起動

$ bundle exec unicorn -c config/unicorn.rb -E production

nginxを再起動

$ sudo service nginx restart

nginxにssl設定

オレオレ証明書を作成

$ sudo mkdir -p /usr/local/ssl
$ cd /usr/local/ssl
$ sudo mkdir -p certs
$ sudo mkdir -p private
$ sudo openssl genrsa -des3 -out server.key 1024 
$ sudo openssl req -new -key server.key -out server.csr

# パスワード入力済みの秘密鍵を生成する。こうしないと、サーバの再起動の度にパスワードを求められてしまう。
$ openssl rsa -in server.key -out private/sslkey.pem

$ sudo openssl x509 -req -days 365 -in server.csr -signkey private/sslkey.pem -out certs/sslcert.pem

nginxの設定ファイル作成

$ mkdir config/nginx
$ vim config/nginx/nginx.conf

unicorn_sample/config/nginx/nginx.conf

・
・
http {
・
・
  server {
    client_max_body_size 4G;
    server_name _;
    keepalive_timeout 5;

    # path for static files
    root /var/www/unicorn_sample/public;

    try_files $uri/index.html $uri.html $uri @app;

    location @app {
      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/unicorn_sample/public;
    }
  }

  # SSL用のserverブロックを追記。これでhttpとhttpsの両方のプロトコルでアクセス出来るようになる
  server {
    # ssl settings
    listen 443 default ssl;
    ssl on;
    ssl_certificate /usr/local/ssl/certs/sslcert.pem;
    ssl_certificate_key /usr/local/ssl/private/sslkey.pem;

    client_max_body_size 4G;
    server_name _;
    keepalive_timeout 5;
    root /var/www/unicorn_sample/public;
    try_files $uri/index.html $uri.html $uri @app;
    location @app {
      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/unicorn_sample/public;
    }
  }
}

nginxを再起動

$ sudo service nginx restart

参考情報

ハイパフォーマンスHTTPサーバ Nginx入門(ASCII)
Web+DB 70号
nginx で ssl 設定をする http://dogmap.jp/2011/05/10/nginx-ssl/