Thursday, January 14, 2010

Hosting Ruby on Rails on scripts.mit.edu

This post describes a method for developing a Rails application and deploying it on scripts.mit.edu, a free hosting service for MIT students and staff. The information here is primarily intended for students in MIT's Web Programming Competition (6.470), but might be useful for other MIT students and staff, as well as for Rails developers deploying in constrained environments.

Summary
The first part of my post shows how to create a Rails application on scripts.mit.edu. By default, the application will use the Rails version that is installed on scripts, which will usually be behind the edge version. The second part of the post copies the application to the developer's computer, and modifies it to use the latest version of Rails. The third part of the post describes the steps needed to deploy a new version of the application back on the scripts.mit.edu servers.

Creating the Application
In the steps below, replace costan with your Athena username, and substitute sixprep with the name of your application.
  1. SSH into Athena: ssh costan@linux.mit.edu
  2. Sign up for scripts.mit.edu and MySQL: add scripts; signup-web; signup-sql
  3. Generate the Rails application: add scripts; scripts-rails app_name
    1. When prompted to enter 1 or 2, enter 1 (you're a user, not a group).
    2. Add the application name to the Desired address: field. For example: http://costan.scripts.mit.edu/app_name
    3. When asked to press Enter to continue, check your application's directory. It should be something along the lines of ~/web_scripts/app_name
  4. Verify that the application works by pointing Firefox to http://costan.scripts.mit.edu/app_name/
Move to the Latest Rails Release
The scripts-rails tool uses the rails command on the server,
  1. Open a command shell in your Eclipse workspace: cd ~/workspace
  2. Copy the application: scp -r costan@linux.mit.edu:~/web_scripts/app_name .
  3. Go into the application: cd app_name
  4. Hack around a configuration bug: ln -s . public/app_name
  5. Install the latest version of Rails: sudo gem install rails
  6. See what the latest version of Rails is (this example assumes 2.3.5): rails -v
  7. Edit config/environment.rb to say RAILS_GEM_VERSION='2.3.5'
  8. Update the configuration files: rake rails:update
  9. Add a requirement (the line below) for the Rack gem to your app's config/environment.rb:
      config.gem 'rack', :version => '1.0.1'
  10. Vendor Rails: rake rails:freeze:gems VERSION=2.3.5
  11. Vendor any other gems that your application uses: rake gems:unpack:dependencies
  12. Follow the steps below to deploy the application back to scripts.mit.edu, and verify that it still works.
Deploy Back on Scripts
The command sequence below will update your application in an almost safe way.
  1. Go into the application directory: cd ~/workspace/app_name
  2. Copy the application to scripts: scp -r . costan@linux.mit.edu:~/web_scripts/app_name
    NOTE: I'm using scp for simplicity. You'll probably want to put sixprep under version control, then remove web_scripts/app_name and check it out from the repository.
  3. SSH into a scripts server:
    ssh costan@linux.mit.edu
    ssh -k scripts

  4. Go into the application directory: cd app_name
  5. Build any new native gems you might have added: rake gems:build
  6. Apply database migrations: RAILS_ENV=production rake db:migrate
NOTE: earlier versions of this post included an extra step for killing FastCGI workers that are caching stale code. The scripts.mit.edu software improved, and this step is not necessary anymore.

The upgrade process is almost safe. The following things can go wrong:
  • a FastCGI worker is spawned with new code, works on the old database schema, and trashes the data (window of opportunity: HTTP requests between steps 2 and 6, assuming the request makes FastCGI spawn a new worker process)
  • a FastCGI worker caching the old code works on the new database schema, and trashes the data (window of opportunity: HTTP request between steps 6 and 7, assuming the requests hits a live FastCGI worker)
It shouldn't be too hard to figure out a solution to these problems, but I decided the windows of opportunity are small enough that I don't care. If you do find a nice and easy solution, please let me know in the comments.

Discussion
This is my method for hosting Rails applications on scripts.mit.edu. It is simple, and it allows me to use the latest version of Rails. There are other strategies that work well.

For example, you could use the version of Rails on scripts.mit.edu (rails -v to find the version on scripts, then gem install rails --version 2.3.2 to install a specific version of Rails). The scripts.mit.edu team back-ported the fixes for security vulnerabilities since 2.3.2 came out, and intends to do so in the future. This might be a better solution, if you don't plan to be proactive about testing and updating your application whenever a new Rails release comes out.

One more thing - in case you're wondering, you will not be able to use scripts.mit.edu with its current software with Rails 3. The reason is that the scripts server use Ruby 1.8.6, and Rails 3 requires Ruby 1.8.7 or above. Unfortunately, Ruby cannot be vendored :)

I hope you found this post useful, and I'm looking forward to your questions and suggestions in the comments.

Acknowledgements
Alice Li and Christopher Luna helped me iron out some bugs in this post by following earlier versions of it.

No comments:

Post a Comment