RailsConf 2006 – What to pick?

17 Jun 2006 In: rails, railsconf

There are three tracks at RailsConf 2006 in Chicago, and all of them are about Rails! How do I choose between all these goodiepacked presentations, demos and discussions? Well, I’m a developer, so it’s in my nature to be analytical – I’ve categorized and prioritized all the talks completely subjective and with no other information than the one found at the RailsConf site. I did this using three principles:

  • Deployment is really hard, so I need get smarter in that area
  • I work in a Microsoft-world, so I want all the Rails vs. Java/.NET stuff
  • I want to experince some of the VIPs from the Rails community

I’ve categorized the talks into six categories:

Development and technologies: Code and technology centered talks
Deployment and performance: Luckily, there a lots of talks on deployment-related matters
Rails vs. “the big boys”: Talks that focus on moving from Java/.NET to Rails
Testing: Talks about testing
Real-world applications: Talks that take a starting point in real Rails applications build by the speakers
General wisdom and entertainment: The infamous “other” category.

I’ve then created this colored overview, and decided which talks I think I will attend (marked with bold):

  Grand North Grand Central Grand South
Friday
10:45 Introduction to Capistrano
Deploying Rails with Capistrano
AC/DC, Stravinsky and Rails
Learn from the creative aesthetics of music – and listen to it!
Tooling Rails
RadRails – why an IDE can be a good thing
13:15 Inside Instant Rails
Packaged Rails environment across platforms
Meanwhile, In The Rest of the World…
How to communicate Web 2.0 to the average Joe
Rails and Asterisk Get A Dental Office Talking
Rails for the medical market
14:30 My Identity on Rails
OpenID – an open source version of Microsoft Password
Rails Application Optimization Techniques and Tools
How to test and optimize performance
Monitoring Rails Applications in Production Environments
Surveillance of enterprise Rails applications
15:45 Rails Deployment on Shared Hosts
Deploying on a shared host with Geoffrey Grosenbach
Overcoming Scaffolding Addiction
Beyond novice development with Amy Hoy
Demos
(The legacy database talk unfortunately seems to have been cancelled)
Saturday
9:00 Ajax on Rails
Lastest and greatest in Ajax
Internationalizing Rails
Discussion of Globalize and localization of Rails
ThoughtWorks on Rails: Experience Reports
Convincing clients that Rails is good
10:15 Domain Specific Languages as Rails Plugins
Demonstration and discussion of DSLs
Rails by the Waypoints: Integrating a GPS Unit and a Digital Camera in the Era of the Mashup
Combining a GPS and a blog
Lessons from Blinksale and IconBuffet
Collaboration, RJS and REST
11:30 Metaprogramming Writertopia
Using metaprogramming with Authorization and Membership plugins
Lucene Eye for the Ruby Guy
Indexing and searching using a Java server
Putting the BBC’s Programme Catalogue on Rails
From green screen to Web 2.0 at BBC
13:30 Beam Me Up Scotty: Rails for the “Enterprise”
Moving from Java to Rails
Using Rails on with Legacy Database Schemas with iBatis for Ruby
Using Rails with a legacy database
Rails Deployment
Workshop setting up a complete Rails box
14:45 Testing Migrations
Ensuring that migrations are correct
Accelerating Rails with lighty
Tuning and scaling of lighttpd
Rails, Ajax and Universal Design
Usability and accessability with Ajax
16:15 Testing Rails Apps
All about testing
17:30 Homesteading: A Thriver’s Guide
Simularities between Rails and rail roads
Sunday
9:00 Beyond DHTML: Introducing Laszlo on Rails
Flash-based application framework
Rails Acceptance Testing with Open Source Tools
Workshop with acceptance testing tools
Agile Databases with Migrations
Best practice, gotchas and legacy in migrations
10:15 Rails Beyond Sites and Full-Form Applications
Rails web services and mobile applications
Just the Facts (and Dimensions) — using Rails with your OLAP data model
Using Rails with datawarehouses
Lightning Talks
Sign for a 5-10 min. slot and speak!
11:30 MetaRails
A look inside the core of Rails
Rails Takes on the Enterprise with SOA
Tying Rails together with Java and .NET
Using Ruby on Rails to Succeed in Selling Music in the 21st Century
Inside e-commerce and community sites
13:00 Deploying Rails Applications
Hard lessons learned about deploying Rails

The RailsConf schedule is like the one for Roskilde Festival (going there after the conference – anyone else?) – they always put the stuff you just don’t want to miss at the same time. In this case, I’d love to attend all the three talks Friday at 15.45, but since questions for Geoff’s talk is already popping up in my mind – and he has a cool voice – I have to go with his talk.

Looking forward to meet a lot of the cool and wise people that populates the Rails community at the conference!

Bookmark and Share

It’s not that I’m the first to describe the process of deploying a Rails application, in fact; it’s rather well-documented, also when it comes specifically to Dreamhost. It’s just that I have a strange combination of circumstances that none of these articles cover, and also; I know almost nothing about Unix-based systems – I don’t even have a Mac. I am one the of many Microsoft-developers who are starting to see the light, and because of that, I need to start entirely from scratch when it comes to understanding the whole Linux/Apache/open-source universe.

(Take me straight to the solution, please)

My strange combination of circumstances
The Rails application I’ve had to learn to deploy the hard way has this configuration:

  • Dependent on Rails 1.1.2
  • Uses Login and User Engine.
  • Build for MySQL (so no problem there)
  • Must run with FastCGI, or it’s too slow
  • Developed with RadRails on Windows XP (yes, this makes a difference)
  • Resides in a Subversion repository

If you can live with Rails 1.0.0, if you don’t use Rails Engines, if you don’t need FastCGI and if you know about Linux, you are probably better off using shorter and simpler tutorials, because these where my specific problems, and what I am going to dvelve into here.

Linux basics
Although it is possible to deploy Rails to a Windows server (and presumably not much harder if you can use Apache instead of IIS), Dreamhost, and all other commercial hosts supporting Ruby on Rails, are using Linux servers. You can develop your entire Rails application completely unknowningly about Linux, but when it gets to deployment you have to learn the basics about this strange operating system:

  • You don’t use Remote Desktop, you use SSH. Remember DOS? When you connect with SSH, you get a text prompt simular to that, and you need to know some basic commands. I recommend using PuTTY for SSH.
  • Use pwd to print you current directory.
  • Use ls to print the contents of the current directory.
  • Use cd (e.g. cd /home/user/) to move into a directory.
  • Use vim (e.g. vim environment.rb) to quickly view and edit files directly on the server. Press your INSERT button to enable editing, and press ESCAPE, then write :wq to save and exit the file.

Now, in a perfect world (see below) you actually shouldn’t have to know this, because Capistrano would do all the dirty work for you, but let’s get real: It’s just not that easy.

In a perfect world
Here is a quick recap of what you would be all needed to do, if the world was perfect or you are extremely lucky and everything works as expected

  1. Now, I expect you have already created MySQL database on Dreamhost and entered the connection details into config/database.yml – otherwise; start out with that.
  2. Create a new fully hosted domain in the Dreamhost panel, and make sure it is configured like this:
    Dreamhost Rails setup
    • FastCGI Support enabled
    • The user has shell access of the type /bin/bash/ (configurable from the Manage Users page)
    • The web directory points to [yourdomain.com]/current/public (not just [yourdomain.com]/public, since we want to use Capistrano)
    • (The www option is up to you)
  3. SSH to [yourdomain.com] and remove the current directory (containing the public directory) Dreamhost has automatically created. (Capistrano needs to create this as a symbolic link later.):
    # On your Dreamhost server
    [nimitz]$ pwd
    /home/cape
    [nimitz]$ cd myrailsapp.com/
    [nimitz]$ ls
    current
    [nimitz]$ rm -r current/
    [nimitz]$ ls
    [nimitz]$
    • Start PuTTY, enter [yourdomain.com] as Host Name and click Open.
    • Login with the user you specified when creating the domain
    • Change to the directory of your Rails application (cd [yourdomain.com])
    • Remove the directories (rm -r current)
  4. Download Geoffrey Grosenbach’s Capistrano script, add it to the /config/ directory of your Rails application, and edit it to reflect your setup:
    # In config/deploy.rb
    set :user, 'cape'
    set :application, 'myrailsapp.com'
    set :repository, 'http://svn1.cvsdude.com/...'
    set :svn_username, "casper"
    set(:svn_password) { Capistrano::CLI.password_prompt }
    • :user must match the user you specified when creating the domain
    • :application must be the domain you created
    • :repository must be the url of your Subversion repository for the application, from where Capistrano will grab the code to deploy.
    • :svn_username only have to be present, if your subversion username is different from your Dreamhost shell username.
    • set(:svn_password) { Capistrano::CLI.password_prompt } tells Capistrano to prompt you for your subversion password. This might not be nescessary, if your Dreamhost user is already in a trust relationship with the Subversion server.
  5. Edit public/.htaccess and change the line RewriteRule ^(.*)$ dispatch.cgi [QSA,L] to RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]. This tells Apache which file it should execute when a request comes in.
  6. Edit public/dispatch.fcgi and change the first line from #!c:/ruby/bin/ruby (or something simularly Windowish) to #!/usr/bin/env ruby. This line is called a shebang location and tells Linux where to find the program that are able to execute this file, in our case; this is ruby.
  7. Edit config/enviroment.rb and incomment the line: ENV['RAILS_ENV'] ||= 'production'. Dreamhost says they set this enviroment variable automatically the nice way when using FastCGI – in my experience, they don’t. This means you have to incomment the line every time you release, and outcomment it again the develop in the development environment – in my final deploy.rb I have a much cleaner solution to this problem, so stay tuned.
  8. Open up a Command Window, move into the directory of your Rails Application and run the command rake remote:exec ACTION=setup. (You will need to type your password for the user you specified when creating the domain)
  9. Run rake deploy. If you are really, really lucky, this will actually do the job for you, and you can browse to your application. If you are not, go on …

Finding out what’s wrong
I’m going to assume that the steps above sort of worked for you, such that Capistrano was actually able to setup the server and copy the files to the correct directory, but it probably failed by the end of the rake deploy command, because it didn’t have the permissions to restart the web server. So now when you go to [yourdomain.com] in your browser, you don’t get a “Page not found”, you get a “Rails application failed to start properly” after a looong wait.

Since the “Rails application failed to start” message is not very information, I am going to start out by giving you a few tips about how to diagnose your failing Rails application. You should be able to distinguish between to scenarios:

  1. Your Rails application is not able to run, probably because it can’t connect to the database or can’t locate some files
  2. The application can run, but the FastCGI link doesn’t work, so pages cannot be served

It’s easy to test for the first scenario; just SSH to the server, cd to the directory of your app (cd /home/user/[yourdomain.com]/current/), and run the command ruby script/console production. This attempts to start your Rails app in production mode, and any error messages will be right there on the screen for you.

The second scenario is in fact also pretty easy to test, at least under the assumption that Apache is able to redirect to “dispatch.fgi” (but it wasn’t, you probably wouldn’t get the “Rails application failed to start properly” error). By running ruby public/dispatch.fgi you actually invoke the same file as the web server, which will often give you handy information.

Once you application is running, you can also get useful debugging information from the log files in the logs directory, but if your Rails app is actually writing to these, you probably have something that are pretty close to work.

Fixing deploy.rb
As I have hinted, I had to make a couple of changes to Geoff’s “shovel” deploy.rb in order to make it run smoothly:

  1. To be able to restart the FastCGI-processes in the :restart task, I had to add ruby to the line that restarts, because the reaper-script that restarts is not executable on Dreamhost. So my :restart task now looks like this:
    # In config/deploy.rb
    task :restart, :roles => :app do
      run "ruby #{current_path}/script/process/reaper --dispatcher=dispatch.fcgi"
    end
  2. To make Apache able to actually execute dispatch.fcgi our deploy.rb also needs to run a command makes dispatch.fcgi executable. On Unix-based systems, any file can be marked as executable, and the OS will then read the shebang location when the file is invoked. By inserting the task below, dispatch.fcgi will be made executable each time you make a deployment. By naming the task after_symlink, it will be executed after the symbolic link has been moved to point to your new files – first by then, the current_path variable is available.
    # In config/deploy.rb
    task :after_symlink, :roles => [:web, :app] do
      # Make dispatcher executable
      run "chmod a+x #{current_path}/public/dispatch.fcgi"
    end

Rails in the /vendor directory
It’s supposed to be so easy to use a different version of Rails than the one installed on your host. Just run rake rails:freeze:gems – or even better: Set /vendor/rails to point to http://dev.rubyonrails.org/svn/rails/tags/rel_X-X-X/ (depending on your prefered version) using the svn:externals feature of Subversion. However, strange things can happen to your application, once all the core files of Rails are suddenly supposed to be read from the /vendor/rails directory. I had to make three crucial changes to avoid various “required file not found” or “NoMethodError” messages after I “froze” Rails:

  1. Move the inclusion of files in config/environenment.rb down to the bottom of this file. For instance; I have require 'taggable' in my environment.rb, and before I “froze” Rails it I just had this line at the top without any problems, but after, it suddenly couldn’t find the taggable stuff, and it only worked when I moved that line down after the whole Rails::Initializer.run do |config| chunk.
  2. Force public/dispatch.fcgi (the file that runs the show) to use the “frozen” version of Rails, by replacing the line require 'fcgi_handler' in dispatch.fcgi with this line:
    require File.dirname(__FILE__) + "/../vendor/rails/railties/lib/fcgi_handler"
  3. Unfortunately, we also need to edit a file inside the Rails framework itself, putting in the absolute location of a required file instead of just the name of the file, as described in this post. However, if you use svn:externals like I do, you can’t just alter a file in vendor/rails, since you don’t have any commit rights. Furthermore, the location of the line we need to add is specific to our setup on the host, so it would be baaad to hardcode it. That’s why I came up with a solution letting the deployment script replace this line on the server using the current_path variable available. You could do this with ruby, but I asked one of my hardcore Linux geek friends to write a one-liner that I could just run, and he chose to let Perl make the replace directly in the file for us. This also happens in the after_symlink task:
    # In config/deploy.rb
    task :after_symlink, :roles => [:web, :app] do
      # Ensure Rails in the vendor dir is used by replacing a line in fcgi_handler.rb
      run "perl -i -pe \"s/require 'dispatcher'/require '#{current_path.gsub(/\//, '\\/')}\\/vendor\\/rails\\/railties\\/lib\\/dispatcher'/\" #{current_path}/vendor/rails/railties/lib/fcgi_handler.rb"
      ...
    end

Rails Engines
Rails Engines is a brilliant way of creating “super-plugins” that acts like small sub-applications inside your application, but where everything can be extended or overriden – even views! If you don’t use engines, this small section is irrelevant for you, but I’d recommend you taking a look a them – I love them.

There is really only one thing you need to be aware of when you deploy a Rails application to Dreamhost that uses engines and has Rails in the vendor directory, and that is to put this code at the very top of your environment.rb:

# In config/environment.rb
module Engines
  CONFIG = {:edge => true}
end

One other thing, not really related to deployment: As I am writing this, the LoginEngine has a problem loading two files in its init_engine.rb, so if you get errors in this file, try replacing the two original require statements with this:

# In vendor/plugins/login_engine/init_engine.rb
require 'login_engine/authenticated_user'
require 'login_engine/authenticated_system'


Wrapping it up: The complete solution
Today, I am able to run rake deploy and it actually works. My deployment script for Capistrano, based on Geoff’s shovel, can be downloaded here. Notice that this script, besides the tasks described above, also automatically replaces #ENV['RAILS_ENV'] ||= 'production' with ENV['RAILS_ENV'] ||= 'production' (incomments it) in config/environment.rb to force production environment on the Dreamhost server.

Here is a complete list of files I’ve uploaded for your reference:

I had to rename some of the files in order to let them be downloadable, but the link listed above has the correct name and the directory the file belongs to.

Please note: You can’t just dump these four files into your own Rails application and expect things to work. You have to carefully extract the pieces from each file you think you need in order to get your application up and running.

Good luck!


Recommended ressources

Bookmark and Share

Getting started using Subversion on Windows

19 Apr 2006 In: subversion, tutorial

Subversion is a brilliant piece of open-source software for version control. It is the heir of the renowned CVS and suprior to the infamous SourceSafe in every way. This tutorial is not about running a Subversion server – although it is easy and free – but about using Subversion for easy collaboration and version control in Windows.

What is version control?

Version control is basically about storing different versions of the same files, which enables you to go back previous versions in case you mess something up. Since the files are usually stored on a central server – often, but not necessarily, accessible from the internet – a nice side effect of version control is that it enables several people to work with the same set of files simultaneously, by letting everyone syncronize their files with the server.

What is a repository?

Remember the central server running Subversion? This is where the repositories is located. Each repository is a unique and seperate collection of files with a forthrunning version number. You usually create a new repository for each new project you choose to version control, but in case you can’t just create new repositories, there is no problem in grouping several projects in the same repository.

I assume that you already know two things: The url of the Subversion repository you want to work with, and the username and password to use with it. If not, feel free to expirement with (but not abuse) a test repository I have setup for this tutorial:

TortoiseSVN – making Subversion easy

Downloading TortoiseSVN

Your first step is to install TortoiseSVN; a free open-source client for working with Subversion in Windows, which integrates seamlessly with Windows Explorer. Go on; download and install the latest version right now! (Select the TortoiseSVN-X.X.X.XXXX-svn- X.X.X.msi file.)

Once installed; start Windows Explorer or open My Computer from your desktop and create a folder a place where you would like to place your first repository – I usually keep mine in “C:\Projects”. Right-click on the folder (or in the “white space” inside it) to discover two new items in your context menu: “SVN Checkout” and “TortoiseSVN”. Select to “SVN Checkout” to make the folder your local working folder for the files in the repository. Enter the url of the repository you want to use, or use “http://svn.casperfabricius.com/sandbox/”. Enter your username and password (both are case-sensitive) or use test as both if you are checking out my test repository. I recommend that you check the “Save authentication” box, unless you are not using your own computer. I might encounter the message saying “Error validating server certificate …” during the process, if the repository is using SSL. It’s not a problem at all, just select “Accept Permantly” and go on with the tutorial. TortoiseSVN will now download any files in the repository to the folder, and add several new items to the context-menu, enabling you to syncronize with the Subversion repository. Your are ready to start using the repository!

1.
Checkout step 1
2.
Checkout step 2
3.
Checkout step 3

Commit and update – your two basic commands

Basically, the point with Subversion is all about sharing your changes with others, and in turn getting their changes reflected in your local working copy of the repository. When you upload you files to the repository on the central server, you are in fact – in Subversion slang – commiting your changes. Every time some one commits a change, the Subversion server creates a new version of the repository. Not that it copies every single file in the repository each time a change is commited, but it creates change sets which enables the server to produce an exact copy of the repository in any given version. Even deleted files still exists in previous versions, so once you have commited something, you can always get it back later, no matter what changes other people make.

So how do you actually commit files? You right on the folder or inside the folder with the files you want to commit, and select “SVN Commit” from the context menu. This brings up an overview of all the files you have changed and new files that has not yet been added to the repository. You must actively check the box for new (non-versioned) files to get added and committed to the repository. You don’t have to add all files in the folder to the repository, actually; you should make sure that generated files – such as dll-files genereated from code files – are not added to the repository.

1.
Commit step 1
2.
Commit step 2
3.
Commit step 3

Updating – as you have probably guessed by now – is simply a matter of selecting “SVN Update” in the context menu and letting magic happen.

Merging and conflicts – two people; one file

But what happens if two people make changes to the same file? The scenario goes like this:

  1. Bob and Alice both change helloworld.txt
  2. Alice commits her version of the file, unknowingly that Bob has also made changes
  3. Now Bob commits his version of file, but get’s an error message; his file is out of date
  4. Bob fixes this by updating his local working copy, and most likely; Subversion is able to merge his changes automatically with Alice’s changes.
  5. If Subversion cannot merge the changes; a conflict occurs.
  6. Bob now needs to navigate to the conflicted file, select “TortoiseSVN > Edit conflicts” and the context menu for the file, manually merge the two files using the build-in program, and mark the conflict as resolved.
  7. Bob are now able to commit his version of the file, which contains both his and Alice’s changes.
  8. The next time Alice update, she gets Bob’s merged file and everyone is happy
1.
Conflict step 1
2.
Conflict step 2
3.
Conflict step 3

Why does it work like this? Why aren’t the files “locked” so only one person can edit a file at the time? Well, for one thing; this way everyone in a team can work unbothered and even offline on the same set of files, and Subversion will (mostly) be able to merge the changes. If you are used to SourceSafe, it will probably take you a bit of time to get used to the idea, but it is – in my opinion – by the best way to work. Embrace merging and even conflicts – they are always easily resolved. If you can’t; Subversion also supports locking, but that’s another story.

One last thing: Subversion can’t (by default) merge binary files. It’s not a problem storing Word-documents, Visio-diagrams, Photoshop-images etc. in a Subversion repository, but once a conflict occurs; you are on your own.

Rearranging – renaming, moving and deleting files.

In time; your repositories grow big and ugly, and you’ll want to rearrange or clean up the mess. When doing this; it’s important to be aware that you can’t just rename, move and delete as you usually do it in “My Computer” or Windows Explorer. Well, you can, but Subversion won’t know it, and will consider a renamed or moved a new file, while restoring the file with the old name in it’s old location on your next update.

For this reason, you should always use the “Rename” and “Delete” commands in the “TortoiseSVN” sub menu in the context menu. This also applies to folders. Also, if you want to move a file to another folder in the repository, you should drag it with right mouse-button and drop it on the folder you want to move it to. This will open a context menu, and when you select “SVN Move versioned files here”, TortoiseSVN will make all the dirty work for you, moving the file to it’s new location.

Rename and delete
Moving a file

The result of sticking to using the rename, delete and move command is that the files will automatically renamed, deleted and moved in other peoples local working copies once they update.

How do I get my own Subversion repository?

If you know me personally, I can probably be persuaded to create a repository for you. If you have our own server, or access to one, you can install Subversion following the instructions on http://subversion.tigris.org/.

Otherwise, there are plenty of companies that offers to fullfill all your Subversion needs. I can recommend these two, since I use them my selve:

Conclusion

I could go on for long about other features of Subversion and TortoiseSVN, but with this; the most basic and important commands and functionality are covered. Happy versioning!

Read more:

Bookmark and Share

Need a web developer?

Hello, I'm Casper Fabricius. I have developed for the web for 9 years, and have been enjoying Ruby on Rails for the past 4.

My experience covers communities, shopping solutions, multi-language sites, heavy back-end lifting and a wide selection of more traditional websites. I like to integrate Ruby with Java and .NET through JRuby and IronRuby when it makes sense. I am passionate about test- and behavior-driven development, but at the same time I am pragmatic and believe in getting things done.

I am based in Copenhagen, Denmark, but I take assignments from across the globe. Feel free to study my resumé, featured projects and - of course - to hire me.