Sep 04 2007

rails environment with lighttpd

Category: Networking, Rubyetd @ 2:49 pm

We want an automated deployment enviroment. The server will automatically (upon restart) detect all the rails applications under a given folder and create virtual hosts for them. No further changes in the server configuration will be required. never. :)

We also want a different virtual host in our domain for each application. For instance if we have a expenses and a blog applications and our domain name is nomejortu.com. We are setting an environment were we will be able to access out applications using http://expenses.nomejortu.com/ and http://blog.nomejortu.com/.

We are using a standard package based installation of lighttpd and ruby:

# apt-get install gcc

gcc is needed for compiling fcgi (fast cgi) for Ruby.

# apt-get install ruby ruby1.8-dev rubygems libfcgi-ruby1.8
# gem install rails
# gem install fcgi

And the web server:

apt-get install lighttpd

The Rails applications will be located under /var/www/lighttpd/rails/ directory and we will have two folders in /etc/lighttpd: railsapp-available and railsapp-enabled. The first will contain the list of available Rails applications, the second - surprisingly - a list of those that we want to enable. With this configuration we will be able to have lots of applications in the server but just enabling (or disabling) them as we need it. Lets prepare this structure:-

# mkdir /var/www/lighttpd/rails/
# ln -s /var/www/lighttpd/rails/ /etc/lighttpd/railsapp-available
# mkdir /etc/lighttpd/railsapp-enabled

The next step is to enable those applications we want to deploy. Say for instance you have app #1, app #2 and app #3 under /var/www/lighttpd/rails/ and right now we only want to deploy app #1 and app #3. We will need to issue the following commands:-

# cd /etc/lighttpd/railsapp-enabled/
# ln -s ../railsapp-available/app1
# ln -s ../railsapp-available/app3

Only applications linked inside railsapp-enabled will be deployed when the server is restarted. To add a new application create a link as shown above, to undeploy an application just remove the link.

No we need the server to be able to understand this settings and only deploy the applications we want. For doing it we will include a script in the main config file that creates the necessary bits of lighttpd configuration required for them to work. Add this line at the end of /etc/lighttpd/lighttpd.conf:-

include_shell "/usr/share/lighttpd/include-app-vhost.rb"

Download the source code for the script and place it in the above location. The code looks like this:-

#!/usr/bin/ruby
 $VIRTUAL_HOST=<<EOV
    $HTTP["host"] =~ "%RAILS_APP%($|.nomejortu.loc)" {
        server.document-root = "/var/www/lighttpd/rails/%RAILS_APP%/public/"
        server.error-handler-404 = "/dispatch.fcgi"
        server.indexfiles = ("dispatch.fcgi")
        fastcgi.server = (".fcgi" =>
           ("localhost" =>
                ("socket" => "/tmp/railsapp-%RAILS_APP%.socket",
                 "min-procs" => 2,
                 "max-procs" => 2,
                 "bin-path" => "/var/www/lighttpd/rails/%RAILS_APP%/public/dispatch.fcgi",
                 "bin-environment" => ("RAILS_ENV" => "production")
                )
           )
        )
    }
 EOV
 Dir["/etc/lighttpd/railsapp-enabled/*"].each do |railsapp|
   puts $VIRTUAL_HOST.gsub(/%RAILS_APP%/,  File.basename(railsapp))
 end

The main loop of the script goes trough the /etc/lighttpd/railsapp-enabled/ directory and for each file it finds there, creates a new block of configuration directives. It does this by replacing the %RAILS_APP% string in the $VIRTUAL_HOST variable with the current name of the application under that directory.

Let’s have a closer look to the generated configuration for each application:

$HTTP["host"] =~ "%RAILS_APP%($|.nomejortu.com)" {
  server.document-root = "/var/www/lighttpd/rails/%RAILS_APP%/public/"
  server.error-handler-404 = "/dispatch.fcgi"
  server.indexfiles = ("dispatch.fcgi")
  fastcgi.server = (".fcgi" =>
    ("localhost" =>
      ("socket" => "/tmp/railsapp-%RAILS_APP%.socket",
      "min-procs" => 2,
      "max-procs" => 2,
      "bin-path" => "/var/www/lighttpd/rails/%RAILS_APP%/public/dispatch.fcgi",
      "bin-environment" => ("RAILS_ENV" => "production")
      )
    )
  )
}

The first line matches the virtual hostname with the application, then we need to customize a few parameters: server.document-root, socket and bin-path that will point to the Rails directory structure of out application.

Don’t forget to make it executable:

# chmod +x /usr/share/lighttpd/include-app-vhost.rb

Remember that adding an application into /var/www/lighttpd/rails will not make it readily available. You still need to add the correct links in /etc/lighttpd/railsapp-enabled and restart lighttpd!

# cd /etc/lighttpd/railsapp-enabled
# ln -s ../railsapp-available/
# /etc/init.d/lighttpd restart
Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Slashdot
  • Technorati

Leave a Reply