Kashia is proud to present you this little tip:

Nitro and Pound

How to use Nitro and Pound

This tip shows how one could set up a few Nitro applications, and load-balance between them using Pound.

Nitro Configuration

Not so much configuration as on how to start the Nitro application.

If you have trouble executing Nitro daemonized (./run.rb -d), you can use one of the scripts I'll describe now, otherwise, just ignore. For all scripts and for starting the application, also make sure that the run.rb is executable (execute chmod +x run.rb if it is not).

Shell script

Put the following script as a file called start_nitro into the same folder as the run.rb of your Nitro application and chmod +x start_nitro it.

#!/bin/sh
echo -n "Starting Nitro on port "
echo $1
./run.rb -m -L --port $1 1>>log/access.log 2>>log/error.log 0>&- &

You can see that I went for the easier way, I just run the Nitro app by hand. You should probably use a mechanism to start/restart the run.rb by using init.d or go for the better way and use real supervising, possibly with Bernsteins daemontools.

In case you're not fully aware, what the above script does:

  • echo -n creates no newline at the end of the output. The newline will be created by echo $1
  • $1 this is like ARGV[0] in Ruby
  • ./run.rb -m -L --port $1 starts the ruby application with Mongrel, in live mode and on the given port.
  • 1>>log/access.log redirects the standard output to log/access.log.
  • 2>>log/error.log redirects the standard error to log/error.log.
  • 0>&- closes the standard input. Reason: when you leave the terminal, the application would be killed due to the standard input being killed off. This also happens with & appended.
  • & This puts the process in the background.

The little script does no error checking at all, so use it correctly.

Ruby script

This script does a bit more, running a given number of Nitro processes starting at a given port.

#!/usr/bin/env ruby

start_port = ARGV.join(' ').scan(/-p\s+(\d+)/).to_s.to_i
instances = ARGV.join(' ').scan(/-n\s+(\d+)/).to_s.to_i

instances.each_with_index do |n,i|
    port = start_port + i - 1
    puts "Starting Nitro on port #{port}"
    system "./run.rb -m -L --port #{port} 1>>log/access.log 2>>log/error.log 0>&- &"
end

Script, graciously donated by manveru

#!/usr/bin/env ruby

# the first letter of the setting is used for parameters
settings = {
  :port   => 8000,
  :number => 1,
  :app  => "/path/to/nitro/app",
  :mode => 'live', # live|stage|debug
  :server => 'mongrel' # mongrel|webrick
}

settings.each do |setting, default|
  arg = ARGV.join(' ').scan(/-#{setting.to_s[0,1]} (.*?) /).to_s
  settings[setting] = arg.empty? ? default : arg
end

p settings

server, mode, port, number, app_path = 
  settings.values_at(:server, :mode, :port, :number, :app)
number.times do |i|
  system("#{app_path}/run.rb --#{server} --#{mode} --port #{port += i} 1>>log/access.log 2>>log/error.log 0>&- &")
end

Pound Configuration

This goes to the bottom (or wherever, inbetween perhaps?) to your pound.cfg which is possibly in /etc/pound/pound.cfg when you are using Debian.

For more help on configuring Pound, visit the Pound website. Especially the part about HTTPS could be interesting, if you're serving a more important site.

ListenHTTP 
    # your IP address/Domain goes here
    Address 62.75.166.87
    Port 80
    
##  
    Service
        # put virtual host config here.
        # HeadRequire "Host:"
        
        BackEnd 
            Address 127.0.0.1
            Port 9998
        End
        
        BackEnd
            Address 127.0.0.1
            Port 9999
        End
        
        Session
            Type IP
            TTL 300
        End
    End
    
    # put other `Service`'es here
End

Observe the Port here, this will be the ports where you want to start your Nitro application at.

Run

First start your Nitro instances.

If you took the shell script:

$ ./start_nitro 9998
$ ./start_nitro 9999

Normal Nitro deamonize:

$ ./run.rb -m -L -d --port 9998 &
$ ./run.rb -m -L -d --port 9999 &

Or one of the two Ruby scripts:

$ ./start_nitro -p 9998 -n 2 &

Last but not least restart Pound or wait 30 seconds, Pound will automatically check the ports if they are reachable. On Debian you would probably restart Pound by executing /etc/init.d/pound restart as root.