Ubuntu Oneiric + nginx + uwsgi + sinatra (rack)
Ubuntu Oneiric (11.10) + nginx + uwsgi な環境で Sinatra アプリを uwsgi に載せるまで。
まず sinatra のインストールから。 apt で sinatra をインストールしたい場合、現在は ruby-rack がみつからず依存関係エラーが出る。
$ sudo -s # apt-get install ruby-sinatra [...] 以下のパッケージには満たせない依存関係があります: ruby-sinatra : 依存: ruby-rack しかし、インストールすることができません E: 問題を解決することができません。壊れた変更禁止パッケージがあります。 # apt-get install ruby-rack [...] パッケージ ruby-rack はデータベースには存在しますが、利用できません。 おそらく、そのパッケージが見つからないか、もう古くなっているか、 あるいは別のソースからのみしか利用できないという状況が考えられます E: パッケージ 'ruby-rack' にはインストール候補がありません
ubuntu-proposed リポジトリに対策済みパッケージがあるので、有効にしてから ruby-sinatra をインストール。
参考:Bug #843734 in ruby-sinatra (Ubuntu): “ruby-sinatra : Depends: ruby-rack but it is not installable”
# vi /etc/apt/sources.list
... deb http://jp.archive.ubuntu.com/ubuntu/ oneiric-proposed main restricted universe multiverse deb-src http://jp.archive.ubuntu.com/ubuntu/ oneiric-proposed main restricted universe multivers ...
# apt-get update # apt-get install ruby-sinatra
Sinatra DSL の Hello World なファイルを作る。
参考:http://projects.unbit.it/uwsgi/wiki/Rack
$ mkdir -p ~/code/ruby/hellosinatra $ vi ~code/ruby/hellosinatra/hello.rb
require 'rubygems' require 'sinatra' get '/hi' do "Hello World!" end
上のファイルを呼ぶ Rack-up ファイル。
$ vi ~/code/ruby/hellosinatra/config.ru
require '/home/cu39/code/ruby/hellosinatra/hello.rb' run Sinatra::Application
uwsgi を設定。 WSGI アプリは mount オプションを使って同じプロセスに複数のアプリをマウントできるが、 Rack アプリだと使えない(やろうとしてかなりの時間を浪費。 rackup ファイルで map すればいいじゃんということかも)。
参考:Mountpoints for Rack applications - uwsgi@lists.unbit.it
# vi /etc/uwsgi/apps-available/hellosinatra
[uwsgi] plugins = rack logto = /var/log/uwsgi/hellosinatra.log chdir = /home/cu39/code/ruby/hellosinatra # mountオプションだと動かない #mount = /hi=/home/cu39/code/ruby/hellosinatra/config.ru rack = /home/cu39/code/ruby/hellosinatra/config.ru chmod-socket = 660 post-buffering = 4096
# /etc/init.d/uwsgi start hellosinatra
nginx を設定。 uwsgi_modifier1 7 が地味にポイントらしい。
参考:http://projects.unbit.it/uwsgi/wiki/RubyOnRails
参考:http://projects.unbit.it/uwsgi/wiki/Rack
# vi /etc/nginx/sites-available/default
server { listen 80; # Make site accessible from http://localhost/ server_name localhost; location /hi { include uwsgi_params; uwsgi_param SCRIPT_NAME /hi; uwsgi_pass unix:///var/run/uwsgi/hellosinatra/socket; uwsgi_modifier1 7; } }
# /etc/init.d/nginx restart
Sinatra::Base のサブクラスにしつつ Haml テンプレートを追加など。
参考:Rubyist Magazine - Sinatra 再入門、 Padrino / Rack / その先の何か
$ vi ~code/ruby/hellosinatra/hello.rb
require 'rubygems' #require 'sinatra' require 'sinatra/base' require 'haml' class Hello < Sinatra::Base enable :inline_templates get '/hi' do @title = "Top" haml "Hello World!" end get '/hi/name/:name' do @name = params[:name] @title = "Song for #{@name}" haml "#{@name}'s Way" end end __END__ @@ layout !!! 5 %html %head %title= @title %body %h1= @title %div= yield
$ vi ~/code/ruby/hellosinatra/config.ru
require '/home/cu39/code/ruby/hellosinatra/hello.rb' #run Sinatra::Application run Hello
もうちょっと試してみる。
require 'rubygems' require 'sinatra/base' require 'sinatra/reloader' require 'haml' class Hello < Sinatra::Base enable :inline_templates register Sinatra::Reloader get '/hi' do @title = "Top" content = "Hi all!" haml :hi, :locals => { :content => content } end get '/hi/name/:name' do name = params[:name] @title = "Song for #{name}" haml :name, :locals => { :name => name } end get '/hi/style.css' do content_type 'text/css' scss :style end end __END__ @@ layout !!! 5 %html %head %title= @title %link{:rel => 'stylesheet', :type => 'text/css', :href => '/hi/style.css', :media => 'screen'} %body = yield @@ hi #header %h1= @title #content %p= content @@ name #header %h1= @title #content #{name}'s Way @@ style @mixin border($width: 1px) { border: $width solid #ccc } div { @include border }
発展:Sthyo: How to Convert From Using Sinatra::Application to Using Sinatra::Base