Deploying Sinatra com Passenger na Locaweb

Posted by caike on January 30, 2009

Com a proposta de ser uma DSL para agilizar a criação de aplicações web em Ruby, o Sinatra permite que uma aplicação inteira seja definida em um único arquivo.

Colocar uma aplicação Sinatra no ar em um ambiente rodando Phusion Passenger (ou algum outro servidor que tenha um handler do Rack) é tão simples quanto desenvolver a própria aplicação, mas requer um pequeno detalhe quanto ao carregamento das gems.

Como exemplo, uma aplicação Sinatra utilizando a gem para comunicação com a API do Twitter.

A árvore de diretórios da aplicação é a seguinte:


./mytwitter
./mytwitter/public
./mytwitter/public/views

A url inicial, ou “/”, exibe um formulário em form.erb (public/views) que submete o login de um usuário do twitter para a url “/list_twits” através do método POST. Esta url é tratada pela aplicação definida no arquivo twitter_app.rb (public), que responde a requisição renderizando um template em list.erb (public/views) com os mais recentes twits do usuário.

A requisição inicial é tratada pelo seguinte método, em twitter_app.rb:


get '/' do
  erb :form
end

Fica muito simples de entender o código apenas lendo a DSL (afinal de contas, é justamente para isso que serve DSL): um método HTTP do tipo GET direcionado para “/” irá retornar um template erb de nome form.erb.

O form.erb é um simples formulário html:


<form action="/list_twits" method="post">
Twitter login:<br/>
<input id="login" name="login" type="text" /><br/>
<input type="submit" value="Get twits!" /><br/>
</form>

O Sinatra também suporta outros tipos de template, dentre eles haml e builder.

Submetendo o form para a url “/list_twits”, a requisição é tratada pelo seguinte método (prepare-se para o maior e último método da aplicação):


post '/list_twits' do
  twit = Twitter::Search.new
  tiwts = twit.from(params[:login])
  @twits = []
  tiwts.each do |t|
    @twits << t.text
  end
  erb :list
end

Este método renderiza o template list.erb enviando a variável @twits junto.

<ul>
<% @twits.each do |t| %>
<li><%= t %></li>
<% end %>
</ul>

Para rodar a aplicação em ambiente de desenvolvimento (onde normalmente utiliza-se Mongrel ou WEBrick) bastaria incluir as gems do Sinatra e do Twitter no próprio arquivo twitter_app.rb. Para deployment com Phusion Passenger e Rack (na Locaweb, por exemplo), é necessário um outro arquivo chamado de config.ru na raíz da aplicação (./mytwitter).

Este arquivo carrega as gems e seta algumas variáveis a serem usadas pelo Rack.


require 'rubygems'
Gem.clear_paths

require 'twitter'
require 'sinatra'

Sinatra::Application.default_options.merge!(
  :run => false,
  :env => :production,
  :views => 'public/views'
)

require 'public/rettiwt_app.rb'
run Sinatra.application

Você pode realizar o deployment com o Capistrano caso esteja utilizando algum controle de versão (o que você DEVE fazer!) ou apenas copiar os arquivos para o servidor via scp ou ftp.

Antes de colocar a aplicação no ar, lembre-se de criar os diretórios no seu server com seus devidos links:


~/public_html/mytwitter apontando para ~/<apps>/mytwitter/public

O código fonte pode ser baixado através do meu github.


Performance Optimization WordPress Plugins by W3 EDGE