Archive for the ‘Deployment’ Category

Monday, April 28th, 2008

I’ve had this before so I should have learnt my lesson. But I didn’t.

I had a site, inherited from another developer, that was migrated to a new server.

The other developer sent me the images associated with the site and I dutifully copied them over. I took a look - lots of “missing image” place-holders, but as this was a work in progress, in a database of thousands of items, I didn’t know what should be there and shouldn’t.

So I asked the other developer to check things over.

No - there should be much more than that” he said.

But look - they are there - in the correct folder on the server!” I replied.

You’re right, ” he said, “but why aren’t they on the site?

It turns out that the code for deciding whether to show the product image or the place-holder looked something like this (with superfluous guff removed):

if File.exists?("#{RAILS_ROOT}/public#{product_image(img, true)}") 
  "<img src="http://blog.3hv.co.uk/wp-admin/#{product.image_filename}" />"
else
  "<img src="http://blog.3hv.co.uk/images/products/image_missing.jpg" />"
end

I spent a while playing around, using script/console on the server (a truly fantastic tool). I asked it to generate the image tag for a given product - it returned exactly what I was expecting. I looked at the equivalent page in the application - it returned the image missing place-holder. But mongrel was running as the same user as script/console - there couldn’t be a permissions issue could there?

Then I remembered …

  • on my dev box, in console and/or test suites, RAILS_ROOT returns an absolute path
  • on my dev box, in mongrel, RAILS_ROOT returns an absolute path
  • on a typical Ubuntu server, in console and/or test suites, RAILS_ROOT returns an absolute path
  • on a typical Ubuntu server, in mongrel, RAILS_ROOT returns a relative path

That was the issue - the file system was getting confused as mongrel gave it a relative path for RAILS_ROOT (ignoring the fact that it should be able to resolve it, no matter how many double dots there were). And even worse, things appeared to be working fine until it was deployed to the webserver.

The fix is simple - add the following to your application controller:

helper_method :rails_root
def rails_root
  File.expand_path RAILS_ROOT
end 

and then replace all instances of RAILS_ROOT within your controllers, views and helpers with rails_root. Problem solved.

Saturday, March 22nd, 2008

Ruby on Rails deployment is often regarded as a dark art. But the guys at Brightbox have made it simple with their Brightbox gem. I have recently moved three clients over - so I’m getting pretty good at deploying there. Here are the steps that I follow:

One:

Sign up with Brightbox and buy a box. You will need to know the account name, the ‘rails’ user password and the mysql password - all of which are available from the VM details page that is emailed to you. The brightbox will be provisioned with a name similar to “account-001.vm.brightbox.net”. I recommend ssh’ing into the box and changing the ‘rails’ user’s password - you will be typing it a lot - or installing your ssh keys.

Two:

Prepare your application in subversion.

You need to make sure that your config/database.yml file is included in your subversion repository (many developers prefer to leave it out for team reasons - don’t worry, you can take it out again later).

You should edit the production entry to point at your desired production database. Set the database name to account_database (where account is your Brightbox account name and database is whatever you want), set the user to your account name, the password to whatever you noted down above and the hostname to sqlreadwrite.brightbox.net (the Brightbox MySql cluster).

Don’t forget to set the svn:ignore property on your log and tmp folders.

Three:

Install the Brightbox gem on your development machine.

Use the brightbox command to generate the Capistrano file (telling it your application name, the name of your Brightbox and the desired domain name that your application will be running on).

At the same time, point your domain name (via an A record) at the Brightbox’s IP address and place a support ticket to set up a Reverse DNS entry (if you will be sending out emails). If you don’t have a domain name yet then use myapp.account-001.vm.brightbox.net.

Then open config/deploy.rb and edit the source code repository entry to point at your svn server (if necessary setting up scm_username and scm_password entries).

Four:

Run the cap setup command (if you have capistrano 2 installed, this becomes cap _1.4.1_ setup as, at the time of writing, the cap 2 version of the gem is still in beta). This will ssh into your server (so you will need that password) and set up the folder structure for you.

Then run the cap cold_deploy command. This tests whether things are working - as it tries to get your code out of svn and onto the server, sets up monit (to keep tabs on your app), uses the database.yml file to create a database and configures Apache with your domain name. If it fails you will need to edit your deploy.rb (and probably get rid of the created database so you can run it again).

You should see your application at your domain name. Stop a second and reflect on how much you have achieved :-).

Five:

Remove your database.yml from svn (set the svn:ignore property on it). Then copy it to the Brightbox (using scp) and place it in /home/rails/my_app/shared/ (where my_app is obviously your application’s name). If you have any file uploads (attachment_fu) or shared assets then copy them into the shared folder as well. Then edit your deploy.rb to add something similar to the following:



task :after_update_code do

  # link the relevant database.yml from the shared folder to the app's folder

  run "ln -nfs #{deploy_to}/#{shared_dir}/database.yml #{release_path}/config/database.yml"

  # link the file store to the application

  run "ln -nfs #{deploy_to}/#{shared_dir}/files #{release_path}/public/public"

end

This means that, after deployment, capistrano will create symlinks from your shared database.yml and shared files into your applications config and public folders respectively.

Six:

Try another deployment to test your symlinking. cap _1.4.1_ deploy - if all goes well then your application should still be running at your domain name, and monit will report that your processes are running correctly. From now on, all you need to do is commit to svn and then cap _1.4.1_ deploy.

Thursday, April 12th, 2007

A nice write-up of getting Rails up and running using Brent’s installer.

Wednesday, April 4th, 2007

I’ve found out what the shared host problem was. I must have upgraded my local copy of Capistrano to the latest. Which changes the permissions used on deployment - instead of 755 they are 775. This causes problems on shared hosts because it effectively means you can execute scripts on other people’s accounts. So a patch has been submitted for Capistrano and you need to add the following to your deployment script.

task :set_permissions do donothing = trueend
Wednesday, April 4th, 2007

I’ve given up on shared hosting - too many variables. Instead I’ve invested in a VPS - meaning I have had to delve into the world of Linux (Fedora 6) administration.

First off, I had to set up my applications to run under mongrel (rather than the FCGI of your typical shared host). I followed the instructions in the “Agile Web Development” book - basically gem install mongrel and gem install mongrel_cluster on both your development box and the server. I also created a new user on the server that mongrel would run under - we wouldn’t want your application running as root would we? Add require ‘mongrel/recipes’ to your Capistrano script and include the line set :mongrel_conf, “#{current_path}/config/mongrel_cluster.yml”. If you are using my staging server instructions then you will probably need to change this - for example I have a mongrel_cluster_live.yml and a mongrel_cluster_test.yml. To create the mongrel_cluster configuration file go to your rails root folder and type mongrel_rails cluster::configure -e production -a 127.0.0.1 -N 3 -p 8000 -c /home/user/applications/current. This creates your mongrel_cluster.yml file - in this case with the production environment, listening to (the server’s) local address, with three processes starting on port 8000 (so 8000, 8001, 8002) deployed to /home/user/applications on the server (the current is the symlink that Capistrano creates).

Run through your normal Capistrano deployment procedure - you should see that the last stage is mongrel_rails cluster::start - in the example above it will attempt to start three mongrel processes on the server on ports 8000, 8001 and 8002. If all has gone well you should be able to point your browser at those three ports and see your application.

Next up is getting your front-end web-server to connect to these mongrel processes. I’m using Apache 2.2 with mod_load_balancer (again as described in the Agile Web Development book) - this is so that requests for myapp.com on port 80 get routed to one of the mongrel processes. This requires editing /etc/httpd/conf/httpd.conf (back this file up before touching it!). Firstly, tell Apache about your mongrel processes:

Proxy balancer://myapp_mongrel BalancerMember http://127.0.0.1:8000 BalancerMember http://127.0.0.1:8001 BalancerMember http://127.0.0.1:8002/Proxy

This attaches the name myapp_mongrel to the three mongrel processes we set up earlier. Then we create a virtual host with the following RewriteRule attached:

 RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f RewriteRule ^/(.*)$ balancer://myapp_mongrel{REQUEST_URI} [P,QSA,L]

This means that any request coming to Apache for myapp.com (or whatever your virtual host is called) is dealt with dynamically (Apache cannot find a static file to serve up in its place) is automatically passed to myapp_mongrel - which we have defined as http://127.0.0.1:8000..8002. So Apache forwards the request to one of your three mongrel processes which deals with it and returns the response back to Apache. Note that we could even set up the Mongrel processes to run on one or more different servers if we desired, spreading any really heavy loads across multiple machines.

This is all good, and nothing too unusual - as I say it’s mostly taken directly from the Agile Web Development book.

However, I also wanted my mongrel processes to start up automatically, should I need to restart the server. So I added some scripts to /etc/init.d. As I said before I had created a separate user for the mongrel processes - I don’t want any security issues compromising the entire server if I could help it. So my start up script (/etc/init.d/myapp - and don’t forget to chmod +x) was slightly different to most.

#!/bin/bash

case “$1″ in start) echo “starting myapp” su - user -c “mongrel_rails cluster::start -C /home/user/application/current/config/mongrel_cluster.yml” >> /var/log/messages ;; stop) echo “stopping myapp” su - user -c “mongrel_rails cluster::stop -C /home/user/application/current/config/mongrel_cluster.yml” >> /var/log/messages ;; restart) echo “restarting myapp” su - user -c “mongrel_rails cluster::restart -C /home/user/application/current/config/mongrel_cluster.yml” >> /var/log/messages ;;esac

Log in as root and try /etc/init.d/myapp restart - you should see mongrel stopping and then restarting. A quick ps aux should reveal your mongrel processes running under the correct user. Genius.

What is happening here is the use of su (switch user). By using su - username (the hypen is important) the script switches user to “username” and loads username’s environment. Then the mongrel_rails command is run - explicitly passing it the configuration file that it needs to use. All output is passed to /var/log/messages for analysis later.

Lastly, we need to tell Fedora to run our script on startup.

Edit /etc/rc.local

/etc/init.d/myapp start

And that is it - getting your application deployed on linux using mongrel and apache. My only other step was to firewall off all ports except SSH and Web - so that no-one could access the mongrel processes directly.

Thursday, March 15th, 2007

Capistrano is one of my favourite Rails features. It’s vital to “agile” development - there’s no point running through your iterations, making fast, small changes, if you can’t easily get them into the hands of the (hopefully) paying public. (It’s also a major reason I’m not too interested in deploying on IIS any more).

However, one of the things I have found is that sometimes you get stuff that runs fine on your local boxes but fails on your server (I had a weird one where Bluecloth worked fine here but not there - despite freezing all my Gems and Rails itself).

So I wanted to set up an intermediate deployment on my server.

A quick hunt found Mike Burn’s article which I then adapted for my own purposes.

Firstly - created a new subdomain and database on my server - and a folder for deploying to.

Then I added a new environment file - /config/environments/staging.rb - this was a copy of development.rb but with code caching turned on.

Next, I set up a new database configuration in /config/database.yml - staging: that points to my newly created staging database.

To get Capistrano to deploy correctly, I amended /config/deploy.rb like so:

if stage == “production” set :deploy_to, “/home/user/myapp_live”else set :deploy_to, “/home/user/myapp_staging”end

I also needed to adapt things after the code had been copied, so the following was added to the end of deploy.rb:

desc “After updating the code, back up the database and migrate”task :after_update_code do run “/home/user/mysql/backup.sh”  # if this is a staging deployment, switch the environment to staging, not production  if stage == “staging”   # switch to the staging environment   run “sed -i ’s/\”production\”/\”staging\”/’ #{release_path}/config/environment.rb”   # migrate the database   run “cd #{release_path} && rake RAILS_ENV=staging db:migrate” else   # migrate the database   run “cd #{release_path} && rake RAILS_ENV=production db:migrate” endend

Basically, I did not trust the deploy_with_migrations task to work the way I wanted it to (I kept noticing rake RAILS_ENV=production db:migrate appearing in the log).

So instead I back up my database manually using a script and then - if I’m in production mode I just migrate the database (explicitly setting the Rails Environment). However, if I’m in staging mode then I use sed to change my environment settings (so that the line ENV[”RAILS_ENV”] ||= “production” becomes ENV[”RAILS_ENV”] ||= “staging”) and then migrate the database (explicitly setting the Rails Environment).

One final step - I created two shell scripts - deploy and deploy_to_production that look like this:

# deploy#! /bin/shcap -S stage=staging deploy# deploy_to_production#! /bin/shcap -S stage=production deploy

These call Capistrano’s deploy task, setting an internal variable stage to “staging” or “production” respectively.

Further Enhancements - I’m going to change deploy.rb so that it uses different Subversion Urls for staging and production - so staging pulls from http://mysvn/myapp/staging and production pulls from http://mysvn/myapp/live.

Monday, February 19th, 2007

Sorry folks - I’ve not been working with IIS recently.

But luckily, others have not been standing still. As well as Microsoft themselves looking at adding FastCGI support to IIS, the number of deployment options you have seem to be growing.

UPDATE: plus this one from Druid (in the comments but reprinted for clarity).

Tuesday, January 23rd, 2007

I rewrote my application to take advantage of the new Restful Urls in Rails (an article on this coming up). I also got rid of the messy session-managed login code and thought I would use a nice and easy HTTP authentication scheme (so my eventual API can use the same mechanism as the main application - plus it minimises that “nasty” server-side state).

All my tests passed. Nice.
I ran through the local application in Camino. Nice.
I capistranoed onto the server. Nice.
I ran through the deployed application in Safari (I wanted to grab some screenshots and I use Shapeshifter - I leave Safari unskinned just for this). Boo! Some of the links didn’t work.

I examined production.log. The filter chain has been halted - no yield. I examined the Rails source code. Why is the filter chain being halted? I looked through the HTTP Authentication source code. It looks like it is working correctly. Why are only some links not working? The authentication is obviously working for part of the application.

Then I noticed. It was the new-style Urls that were failing … http://myserver.com/thingies/34;edit - it’s the semi-colon! A few more tests proved it.

And then the killer. It works fine in IE (both 6 and 7). It works fine in Camino. It works fine in Firefox. It’s just Safari. Apple’s flagship browser doesn’t work with Apple-loving Rails. I then tested in OmniWeb … no joy there either. So WebKit doesn’t like Restful Rails.

A quick search later digs up this article - with a fix. Basically it overrides url_for and examines the User Agent - if it’s AppleWebKit then Url-escape the semicolons. My Urls look ugly but at least they work.

Wednesday, January 3rd, 2007

Brent Heinz contacted me last year asking me to point to his new installer. It’s taken me a while to get round to it but here it is … automating all the rubbish that I wrote about all those months ago.

Tuesday, January 24th, 2006

Update: Brent Heinz has written an installer to automate this.

Last time I wrote about setting up Rails on IIS I was in a bit of a rush. However, this time, hot on the heels of an installation on a live customer site, on Windows Server 2003, I have decided to rewrite the original article.

The process I’ve followed here has worked on IIS on Windows 2000 Server, Windows XP and now Windows Server 2003. I don’t know which versions of IIS were involved but the same basic process has been used across all three. I’ve not quite managed to get web services working over IIS but I reckon I’m not far away - so follow the instructions below and I’ll update you when we get there.

So where do we begin? First of all, collect all your bits and bobs together. In particular you will need

Ruby is for obvious reasons.

Rails is useful as I found that 2003 is so locked down that gem did not have access to download the framework from rubyforge.

The DBI-ADO interface is needed for a single file, ADO.rb, that allows the SQL Server adapter to connect to MS-SQL.

Ruby for IIS does some patching to Rails and Ruby to allow IIS to route its requests to FastCGI and eventually to Rails. In the interests of full disclosure I should say that I have not looked at the source of this and so do not know exactly how it works. I will get round to it, promise.

FastCGI keeps a number of Ruby/Rails processes running within IIS. This means that when a request comes in from a client you do not need to start a new Ruby process (and hence incur the not insignificant cost of loading all the libraries) every time. Instead FastCGI starts N processes and if all are busy will start more, upto a maximum of M processes and routes requests to whichever process is free.

The Ionic Rewriter takes a Rails-friendly url (controller/action/id) and rewrites it into a form that IIS understands. IIS then dispatches this new URL to FastCGI which in turn passes it to Ruby.

So, you’ve installed Rails (into C:\Ruby) and copied your application files over (into D:\MyApp). You’ve added the Rails framework into your application’s vendor folder (D:\MyApp\vendor) - this is because we will be altering some of the framework files so we want to keep our changes (in D:\MyApp\vendor) separate from the main Rails installation (in C:\ruby\lib\ruby\gems\1.8\gems). You then need to extract ADO.rb from the DBI file and place it in C:\ruby\lib\ruby\site_ruby\1.8\DBD - you will need to create an ADO folder and place the file into there.

Next up, edit your application’s configuration file (either one of the environment specific ones, or your general one - you decide) and add the line:

ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:tmpdir] = 'D:\\Temp\\'

. You will need to create a Temp folder on D: or your application will silently fail to work. The point of this is to force Ruby to place its session files into a known folder - if you read back through this blog you will find that at one point I was having strange behaviour with sessions. It turns out that as you run under different configurations (CGI, FastCGI and WEBrick) Ruby sometimes places its files in different locations and you get unpredictable behaviour. Plus it also helps when you need to clean up your sessions (which you will need to do later).

Now run your application under WEBrick. This is vital. If it doesn’t work here it definitely won’t work under IIS. Don’t say I didn’t warn you. What? It didn’t work under WEBrick. I bet you forgot to edit your database.yml file. Go and do it now and test it again. Still doesn’t work? Seems to fail silently with no entries in your log file. I told you - create a D:\Temp folder and you should be OK.

Copy your ISAPI files to a safe place - I tend to put them in C:\InetPub - they are associated with IIS but not available to the public. This means copying your FastCGI.DLL and IsapiRewrite4.DLL and IsapiRewrite4.INI files to wherever. Watch out, the Ionic Rewriter DLL and INI file must live in the same folder.

Fire up the trusty pain-in-the-arse Internet Information Services configuration manager. The instructions here are for setting up one site on the “Default Web Site” - I don’t think it will be too hard to set up multiple Rails sites on one IIS site and even easier to set up multiple IIS sites, each containing a single Rails site. But I’ve not done it so I won’t go on about it here.

Right-click on your “Default Web Site” and select “Properties”. Select ISAPI Filters. Click Add and enter a filter name of “Rewriter” and select the IsapiRewrite4 DLL.

Next, switch to the “Home Directory” tab. Make sure “a directory stored on this computer” is selected and set D:\MyApp\Public as the local path. Put your application name into “Application Name” (if this is greyed out then click “Create” to set up the site as an application) and make sure “Scripts and Executables” is selected for “execute permissions”. Next up, click “Configuration”. Under “Mappings” click “Add” and select FastCGI.DLL as the executable, .fcgi as the extension (if you are going to have multiple Rails applications on a single server you need to vary this extension on a Rails-application-specific basis - for example .myapp1, .myapp2 etc), with “All Verbs”, “Script Engine” and “Check that file exists” all selected.

If you’re on Server 2003 there is an extra step. You have to allow IIS access to the executables you are going to be using. Create a new Web Server Extension in the IIS Configuration Manager, calling it “MyApp”. Add FastCGI.DLL, IsapiRewriter4.DLL and RubyW.exe to this extension and make sure that it is enabled.

Phew - what have we done so far?

  • We’ve installed Rails and our application and made sure it works OK under WEBrick
  • We’ve told IIS that the default web site for this server is our application’s public folder
  • We’ve told IIS that any request to the default web site should be fed through the Ionic Rewriter
  • We’ve told IIS that any request for a .fcgi file should be fed through FastCGI

What we’ve not done is tell Ionic or FastCGI how to behave.

Ionic first. Edit IsapiRewrite4.INI - get rid of the contents of the file and replace it with

# Ruby on RailsIterationLimit 0RewriteRule ^(/[^.]+)$ /dispatch.fcgi?$1

This takes the URL that IIS recieves and matches it against the given regular expression. I’m no grexpert but I’m reliably informed that it matches any string starting with a ‘/’ that does not contain ‘.’s. If you are setting up a web-service then this has an implication - by default Rails makes the WSDL available via a URL ending in service.wsdl. You will need to edit D:\MyApp\config\routes.rb to change this to something like service_wsdl - otherwise the URL rewriter will spot the ‘.’ and will not feed the request to Rails at all. (Of course, I haven’t got web services working with these instructions yet but I will. Oh yes, I will). Anyway, so it matches any URL starting with a ‘/’ and not containing a ‘.’ - and rewrites it to /dispatch.fcgi?$1. So /controller/action/id will be matched to /dispatch.fcgi?/controller/action/id.

Hang on - our URL is being rewritten with a .fcgi in it - ring any bells? That’s right, next up we configure FastCGI. Open RegEdit and open the Local Machine/Software key. Create a key (folder) called “FastCGI”. Under here create another key (folder) called “.fcgi” - when FastCGI is invoked with a file extension of .fcgi it will use the settings in this key. This is why, when we have multiple applications on a single server, we need to vary the file extensions (.myapp1, .myapp2 as detailed above - likewise we need to rename dispatch.fcgi to dispatch.myapp1/dispatch.myapp2 for each respective application). The basic FastCGI setttings we need (we’ll add some more later) are:

  • AppPath - set this to C:\ruby\bin\rubyw.exe
  • Args - set this to D:\MyApp\public\dispatch.fcgi
  • BindPath - set this to MyAppRailsCGI

. AppPath tells FastCGI that we want Ruby (the “windows” version that does not produce a command line output) to execute our scripts, passing it the Args (our dispatch.fcgi script) as the entry point to the application, using the Named Pipe “MyAppRailsCGI” to communicate.

Now, use the IIS Configuration thingy to restart IIS - right-click on the Server, select All Tasks and restart. This seems to take forever on Server 2003. Now open your favourite browser and point it at your application (http://myserver/controller/action/id or whatever). Now I’m betting that you get a “recognition failed for dispatch.fcgi”.

Let’s take a walk on the dark side. I’m not 100% sure what is going on here. It involves regular expressions and environment variables that I can’t access in debug mode and it all seems to happen before Rails’ logging is invoked. So this is guesswork that seems to be effective (apart from web-services, which, as I have said before, I will return to some other day). Go to D:\MyApp\vendor\actionpack-version\lib\action_controller\request.rb - this is the Ruby file that ActionPack uses to route URL requests. Under Apache and WEBrick, it returns the REQUEST_URI environment variable, and if it can’t get at it, it manipulates PATH_INFO and SCRIPT_NAME to get the same result. Under IIS it doesn’t work - what the method is expecting is a “SCRIPT_NAME” of “/dispatch.fcgi” (which is what we have) but a “PATH_INFO” of “/dispatch.fcgi/controller/action”. In other words, instead of extracting the original URL and making it into a query string, it expects the original URL to be tacked onto the end of the dispatcher script. The problem with this is that if the URL looks like that, then the URL no longer ends with .fcgi so IIS does not know to ask FastCGI to process the request. Our PATH_INFO looks more like “/dispatch.fcgi?/controller/action” - note the all important question mark in the URL. However, if we modify the request_uri method in request.rb to look like:

# Returns the request URI correctly, taking into account the idiosyncracies # of the various servers. def request_uri   if uri = env[’REQUEST_URI’]     (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri # Remove domain, which webrick puts into the request_uri.   else  # REQUEST_URI is blank under IIS - get this from PATH_INFO and SCRIPT_NAME     script_filename = env[’SCRIPT_NAME’].to_s#.match(%r{[^/]+$})     uri = env[’PATH_INFO’]     uri = uri.sub(”#{script_filename}”, “”) unless script_filename.nil?     uri <<>

I’m 99% sure that this edit is what is making the web-services fall over. However, it does mean that traditional sites (that don’t use query strings) are routed correctly.

Restart IIS (again .. yawn) and try connecting once more. After a long pause (as FastCGI invokes Ruby for the first time) you should see your application. Congratulations. Have a cup of tea.

Now to reconfigure FastCGI again … reopen RegEdit and move to your .fcgi key. Add entries for StartServers (DWORD), IncrementServers (DWORD) and MaxServers (DWORD). This tells FastCGI how many copies of Ruby to start initially (I tend to use 5), how many to start at times of high load (I tend to use 3) and the maximum number of Ruby processes to have running at one time (15 if your server can handle it). I also tend to set the Timeout (DWORD) to 600 - if FastCGI needs to start extra Ruby processes it will keep them alive for ten minutes before shutting them down again. And your last one - add a BINARY key called Environment - and type in RAILS_ENV=PRODUCTION for the value. In Regedit you can directly enter the value for binaries by typing in the right hand side of the edit box - you don’t need to convert each character into Hex, like I did the first time I was confronted with this editor!

And there you have it. Your Rails application (sans web-services) should be up and running on your IIS server. It should have 5 concurrent Ruby processes dealing with incoming requests, increasing to 15 processes under load.

Hope that helps … enjoy.

Oops - almost forgot. Create a batch file (D:\MyApp\Scripts\cleanup.cmd) that contains the line del D:\Temp\Ruby_Sess*.*. Then add a scheduled task to run that batch file every night at some god-forsaken hour. This cleans up Ruby’s session files and prevents too many from being created. Of course, ideally, you would examine the last-changed-time and only delete those that hadn’t been touched in twenty minutes, or whatever, but, for my application at least, getting rid of all of yesterday’s sessions is good enough. Your mileage may vary.