An existing Apache webserver is to have a new webapp added to it, in a subdirectory of the DocumentRoot. Sinatra is the framework to be used, and Passenger is going to route requests from Apache to Sinatra without going through any mod_proxy or mod_rewrite business.
Assume the following: Apache2, an Ubuntu system, and all of the relevant gems have been apt-get installed. The web server root directory is /var/www, and the webapp will be in /var/www/timon.
First, update the Apache config file (/etc/apache2/apache2/conf):
<VirtualHost *:80>
ServerName Apemantus
DocumentRoot /var/www
<Directory />
Options -Indexes
AllowOverride None
</Directory>
<Directory /var/www/>
AllowOverride AuthConfig
Order allow,deny
</Directory>
SetEnv RUBYLIB '/var/www/timon'
PassengerEnabled on
PassengerAppRoot /var/www/timon
RackBaseURI /timon
</VirtualHost>
The bold lines indicate what must be added.
- SetEnv : This just allows the code in subdirectories of the webapp to be easily required.
- PassengerEnabled : Seems fairly obvious.
- PassengerAppRoot : The full filesystem path to the webapp directory.
- RackBaseURI : The relative (to DocumentRoot) path to the webapp directory.
Next, verify that the Passenger options (/etc/apache2/mods-enabled/passenger.conf) are correct:
<IfModule mod_passenger.c>
PassengerRoot /usr
PassengerRuby /usr/bin/ruby
PassengerMaxPoolSize 10
PassengerDefaultUser www-data
</IfModule mod_passenger.c>
These options are pretty straightforward. The only thing to note is that PassengerRuby can be set to a specific version of Ruby, e.g. jruby or ruby1.9.
Now, create an empty Rack-friendly directory structure for the webapp:
bash# cd /var/www
bash# mkdir timon
bash# mkdir timon/public
bash# mkdir timon/tmp
The use of public for static pages and tmp for restart.txt is well-documented.
Next, a Rack config file must be provided. This will be named config.ru (/var/www/timon/config.ru) and will have the following contents:
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
# Disable Sinatra's default Webrick instance
set :run, false
# Include timon.rb, the main webapp script
require 'timon'
run Sinatra::Application
Finally, the app itself must be provided. This will be named timon.rb (/var/www/timon/timon.rb) and will have the following contents:
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
get '/' do
"<b>TIMON!</b>"
end
# Local 404 handler
not_found do
"Timon NotFound exception"
end
# Local error handler
error do
"Timon Error: " + env['sinatra_error'].name
end
Debugging can be made a bit more straightforward by adding some basic logging code to config.ru:
#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
# Disable Sinatra's default Webrick instance
set :run, false
# Local logging
FileUtils.mkdir_p 'log' unless File.exists?('log')
log = File.new('log/sinatra.log', 'a')
$stdout.reopen(log)
$stderr.reopen(log)
# Include timon.rb, the main webapp script
require 'timon'
run Sinatra::Application
That's it.
Nothing much to it, really, but the lack of RackBaseURI in the relevant examples really makes debugging this kind of thing difficult.