LoginSignup
174
165

More than 5 years have passed since last update.

AWSで、unicorn + nginx + sinatra を動かしてみる

Posted at

構築を試みたときに調べたことなどなど

なぜunicorn + nginx?

unicorn

unicornは汎用のRackアプリケーションサーバ。Railsからもsinatraからも使える。

unicornだけでも、任意のポートをlistenすればwebサーバーとして使えるが、
以下のようなメリットがあるため、本番ではnginxをリバースプロキシとして
前に立ててからリクエストをunicornに流すのが良い

  • 画像やcssなどの静的ファイルはnginxで高速に返せる

  • リクエストをバッファリングして受信完了してからunicornにリクエストを
    投げるため、遅い回線(3Gなど)で接続が来た時にunicornの
    ワーカプロセスの待ち時間を削減できる

動作原理はgithubの運用例が記載された以下のドキュメントが詳しい
https://github.com/blog/517-unicorn

まずは、unicornだけでサーバーを立てる

サンプルのsinatraアプリをunicornから呼んでみる

config.ru
require 'rubygems'
require 'sinatra/base'
class HelloApp < Sinatra::Base
  get '/hello' do
    'Good Sunday Morning!'
  end
end
run HelloApp

Gemfileにunicornを足して、bundle installする

Gemfile
gem "unicorn"
shell
$ bundle install
$ bundle exec unicorn -v
unicorn v4.6.3

unicornの設定ファイルを作る。rubyのコードで書けてgood。

unicorn.rb
@dir = "/path/to/app/"

worker_processes 2 # CPUのコア数に揃える
working_directory @dir

timeout 300
listen 80

pid "#{@dir}tmp/pids/unicorn.pid" #pidを保存するファイル

# unicornは標準出力には何も吐かないのでログ出力を忘れずに
stderr_path "#{@dir}log/unicorn.stderr.log"
stdout_path "#{@dir}log/unicorn.stdout.log"

AWSを使っているなら、セキュリティグループで指定したportを
空けておく(よく忘れてハマる...)

これで準備完了。以下のコマンドで起動できる。-Dはdaemonとしての起動。
本番環境で起動する時は-E production とする
(※ オプションは設定ファイルより優先される)

shell
$ bundle exec unicorn -c unicorn.rb  -D
$ ps auxf | grep unicorn | grep -v grep
unicorn master -c unicorn.rb  -D
 \_ unicorn worker[0] -c unicorn.rb -D
 \_ unicorn worker[1] -c unicorn.rb -D

psを見ると、workerプロセスとそれを管理するmasterプロセスが
動いていることが確認できる

また、unicorn_railsという実行ファイルもあるが、こちらは
過去verのRails向けで、基本的にはunicornを使うことが推奨されている

nginxをリバースプロキシとしてunicornの前に置く

次に、nginxをunicornの前に置く

unixドメインソケットを経由してnginxとunicornがやりとりを行うよう設定
また、/path/to/app/static以下のリクエストはnginxが処理する(unicornまでいかない)

shell
$ sudo yum -y install nginx
$ nginx -v
nginx version: nginx/1.4.2
/etc/nginx/nginx.conf
user  root;
worker_processes  2;

http {
    upstream unicorn_server {
       server unix:/path/to/app/tmp/unicorn.sock;
    }

    server {
        listen       80;
        server_name  ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com;
        root         /path/to/app/static;

        location / {
            # 静的ファイルが存在しなかった時はUnicornにproxy
            if (!-f $request_filename) {
                proxy_pass http://unicorn_server;
                break;
            }
        }
    }
}
unicorn.rb
# listen 80
listen "/path/to/app/tmp/unicorn.sock", backlog: 1024 # UNIXソケットを見るように変更

nginxを起動,unicornを再起動
ブラウザでhttp://xx.xx.xx.xx/hello を叩いて確認

shell
$ sudo /etc/init.d/nginx start
or
$ sudo nginx

ネクストステップ

以上でとりあえずは動くが、他にもunicornには調べておくべきトピックが
あるので、いくつか挙げておきます

  • linuxシグナル送信によるunicornの起動/停止

  • capistranoを用いてホットデプロイを実現する

  • preloadを有効化してリロード速度の応答低下を回避する

Have Fun!

174
165
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
174
165