Archive for the ‘Ruby On Rails’ Category

Hoptoad – Rails Exception Catching Made Easy

Posted on August 27th, 2008 in Programming, Ruby On Rails, Services | View Comments

Have you ever installed the Exception Notification plugin in one of your Rails apps, just to get bombarded with E-Mails of the same error over and over again? It’s happened to the best of us.

Thankfully, people in the Rails community have been working on different solutions to handle this. One I discovered recently, which I’m really loving a lot, is Hoptoad, brought to you by the awesome people over at thoughtbot. Really, how can you not be an awesome group when your blog is titled Giant Robots Smashing Into Other Giant Robots?

Anyway, Hoptoad is a service which captures all exceptions that occur in your Rails application, and aggregates them into one place. This way, if you have, for example, a link to AJAX functionality that causes a 500 error, you’ll only get one E-Mail notifying you about the error. The service will actually log the times it’s happened, though. It also provides a full stack trace, session information, parameters that were passed, and just about everything else you need to make a full assessment on why your application failed. Oh, and one more important thing: it’s totally free. Can’t beat the price.

It’s as simple as creating a new account and setting up a project, installing their plugin on your application, putting the assigned API key in an initializer file, and that’s it! It took me about 2 minutes to set everything up the first time. The interface is pretty straight-forward. When you first log in, it will show if any of your projects has any errors (which any developer can mark as ‘Resolved’ so it won’t show again). If there are (and face it, we all get errors at one point or another), then as I mentioned previously, you can view the stack trace to see what happened. Nice, simple and helpful.

I’ve noticed there are some other sites that offer these services (like Exceptional), but none that seem to have the simplicity of Hoptoad. Not that I think the other services are bad, but it’s just not what I want at this moment. In my particular case, I really don’t need to have an app that integrates with other services, let’s me leave comments about an error, or see how many times in the past week the error occurred. I just want to know if my app is getting errors. Hoptoad does just that.

I fully recommend Hoptoad for any Rails app. If you don’t have any sort of exception notifier in your app, you should get something now. If you do, then I hope you never have to constantly use it!

That Was Easy – Upgrading From Rails 1.2 to Rails 2.0

Posted on July 31st, 2008 in Programming, Ruby, Ruby On Rails | View Comments

It’s been an interesting week for me. I got a first-hand taste on upgrading a Rails 1.2.x application to Rails 2.0. To be honest, I was terrified when this task was presented upon me. I had never done this before, since virtually all the Rails 2.0 (and 2.1) apps I’ve worked with have started with that particular version, not an upgrade. Seeing that the application in question had been under development for a long time (hence still using Rails 1.2), I immediately though that an upgrade to Rails 2.0 would cause the app to break so bad, I would be having “NoMethodError” messages in my nightmares for a long time to time.

So with the thought of a long week of fixing trivial changes to make the application work correctly once again, I removed the frozen Rails 1.2 directory from the application and froze Rails 2.0 in its place. I started Mongrel, and… It worked. Like it really worked. Well, not 100%, but most of the application worked as it was before! I definitely couldn’t believe it. That was probably the easiest framework upgrade I’ve done in my entire life. Most of it had to do because of me doing a lot of refactoring for code that I had knew would be removed from the framework soon, but also kudos to the Rails Core team for making this pretty straightforward.

Like I said, it didn’t go 100% smoothly, so I thought I’d share some of the gotchas I encountered during the upgrade.

‘extract_options_from_args!’ method

The extract_options_from_args! method was apparently removed in Rails 2.0. Upon further inspection, there were many plugins using this method, but only one (nested_has_many_though) wasn’t properly handling it. All I had to do was update that particular plugin, and the error disappeared from the entire application. So my recommendation is to upgrade any currently existing plugins you have, although this is more tricky if you have old plugins that aren’t being currently maintained.

‘You are being redirected’ problem

In some places of the application, when an action used ‘redirect_to’ to send me somewhere else, a page would appear, simply saying ‘You are being redirected‘, with a link to where the app should’ve been redirected. The problem: there was a parameter named ‘status’ that was used for the redirect. Changing the parameter name to ‘state’ solved the problem. I’m guessing it’s because Rails uses the word ‘status’ to set the HTTP code for a redirect, so it caused this hiccup.

‘Called id for nil’ error

I was also getting errors for nil variables where they didn’t exist before. The problem here was caused because some ‘form_for’ tags were using variables that weren’t initialized previously in the controller. Taking for example the following code: <% form_for @item, :url =>items_path do |f| %>. The instance variable ‘@item’ wasn’t declared in the controller (or the view, although if someone did that, I would hunt them down), yet in Rails 1.2 it would work properly. It was just a matter of adding @item = Item.new in the controller for the action, and it would work fine again. I guess this was just done to make sure things are coded correctly, which I really don’t mind.

Route Globbing and escaped slashes in URL

This one was an interesting one. Part of the application uses route globbing, where you can set a route to grab everything in a URL and set an array. The application in question was using this in one part of the application, to get a collection of IDs and process them for some other functionality. However, this was being done via a link generated using ‘link_to’, which promptly went to escape the slashes between the IDs (from ‘/’ to ‘%2F’, which the browser read well, but Rails 2.0 apparently doesn’t like), and the route globbing wouldn’t return the array as expected. For example, previously in Rails 1.2, if the URL ended like items/process/101/105/110, the route globbing would return an array of three elements: ["101", "105", "110"], which is what the app expected. In Rails 2.0, since the slashes were escaped thanks to ‘link_to’, it would return an array of one single element: ["101/105/110"]. This problem was already reported and seems like it’ll be fixed in Rails 2.1.1. But in the meantime I did a quick fix: take the element in the array and split it using Ruby’s split method to create the array as it should be before processing.

Besides these errors, the rest went smoothly. The app has been running for two days under moderate testing, and nothing else appears to be broken. So it all went well. Hope this post helps someone get through some problem upgrading their old, creaky Rails app.

PeepCode – Even their PDF books are awesome

Posted on May 2nd, 2008 in Books, Ruby, Ruby On Rails | View Comments

This is obviously not my first time that I have shilled the PeepCode website. I truly think that for any Rails developer, this is one of the most invaluable tools for learning available anywhere. I’ve purchased many of their screencasts already, and once I get the opportunity, I’ll even spring for their PeepCode Unlimited subscription. I know I will fully get my money’s worth.

If you haven’t been following what they have been doing recently, they have also added PDF books to the mix. These books provide a lot of wealth, just like their screencasts, but only in text form, perfect for printing or, for the environmentally-conscious of you, just keeping in your flash drive and reading it whenever you need it. I just recently purchased two of their PDF books: Git Internals and ActiveMerchant.

I purchased the Git Internals book to satisfy my own curiosity. As many of you should know by now, Git is a distributed version control system (a la Subversion) that’s taking the software development world by storm. I’m slowly getting into Git, thanks to a PeepCode screencast on the basics of Git, and even decided to pay for an account on GitHub (which I will write about in the near future). But I’m usually not content to just know how to get my work done. I like exploring beyond that, knowing how it actually works in the inside. Most of the times, I fully understand its strengths (and weaknesses – nothing is perfect!), making me more efficient. This PDF book does exactly that. If you’re a curious being, and are using (or planning to use) Git, I wholly recommend this book.

The ActiveMerchant book, I actually bought out of necessity. The web application I’m working on has the ActiveMerchant Plugin installed, and some work with that plugin done. However, since the developers who implemented those features aren’t working for the company anymore, and some core functionality has changed since I’ve arrived, it needs to be changed. I didn’t want to start from scratch, so I bought this PDF book to see what should be the “right way” (as per the author, who undoubtedly has tons more experience with the plugin as I have). I really got into this book, because it’s really, really easy to understand (thanks to the plugin actually being easy to implement) and it explains everything you need to know about the entire payment process. This is a must-read for anyone who’s building Rails applications where money needs to get to you.

The guys over at PeepCode are doing an excellent job, so why don’t you head over to their site and check them out? If you’re a web developer, particularly using Ruby and Rails, you’ll definitely find something interesting, or even necessary.

Advanced Rails Recipes – Sort Of A Review

Posted on January 6th, 2008 in Books, Ruby On Rails | View Comments

Like I mentioned a while back in this blog, I really like the books released by The Pragmatic Programmers. They’re pretty easy to read and teach a lot in the process. Although Programming Ruby (known to many on as the ‘Pickaxe’ book) is getting some flak after Zed Shaw’s take on it (which I agree on, although I’ll give my own take on it in the near future), you can’t deny their books are among the best in their specific topics.

I’m a big fan of the Rails Recipes book (and no, it’s not because they actually put a pilón, a typical Puerto Rican food prep utensil, on the cover). When you learn a specific technology, be it a programming language, database engine, framework, or anything else, you’ll want to find some real-world usage to apply what you’ve learned. Books like Rails Recipes give you an entire list of specific things you probably thought of doing for your own application, but didn’t know how to exactly do it. It’s a great tool when you’re developing your own stuff.

Of course, thanks to the speed of Rails, that book is a bit outdated. So I was really psyched that a new version, named Advanced Rails Recipes, was going to be released in March 2008. So psyched, that I actually went over to their site and purchased the beta PDF (and, of course, I’ll be getting the paper book wne it’s released). I couldn’t wait to read it and apply some recipes to my current projects.

First, I would like to discuss the current system that’s used for beta PDF’s in the Pragmatic Programmers site. The site is relatively easy to use, and really well done. Once I created an account and purchased the PDF and paper book, I received an E-Mail stating that my PDF was ready to be downloaded. That was it. Withing a few minutes, I already had my PDF, with “This book was prepared exclusively for Dennis Martinez” in the cover – neato! A couple of days passed by, and I received an E-Mail stating that the beta PDF was updated. All I needed to do was to go into my account on their site, and a link immediately appeared in the main page, which took me directly where to regenerate the PDF (which apparently is run by gerbils – no joke!). A few minutes passed, and the gerbils sent an E-Mail with a link to my updated PDF. Okay, so they might not really be gerbils who work on the PDF’s, but I really like it when companies go with these informal jokes while still be very helpful. Kudos to these guys for making a very user-friendly site.

This book is filled with recipes from various Rails users all around the globe who have contributed their work to this book. One thing that took me by surprise is the fact that I expected this book to be pretty much incomplete, with tons of errors all around, but it really wasn’t like that at all. I found one or two spelling errors, and the recipes I tried worked straight out of the box. That’s a great thing, because this is why I went ahead and purchased the book three months in advance. I wanted to read up on the techniques used by people with much more real-world Rails experience than I.

In particular, I wanted to read up on the chapter about Capistrano and deployments. This, to me, is one of the most touchy issues in Rails nowadays. It’s something that everyone seems to do differently with mixed results. The recipes included here aren’t de-facto deployment strategies, but nice techniques, such as how to generate config files on the fly when deploying to a remote server, how to safeguard your database passwords so that they’re not in your source code repository, and many other techniques.

Sure, most of these recipes are readily available on the Internet, if you search hard enough. But when you’re developing a major web application, the last thing you want to do is to fire up Google and spend the next 15+ minutes searching and trying out pieces of code to see if they work for you. This book avoids all that. Not only does it show you how to do things, it also explains why and when you should use them.

Major kudos to the author, Mike Clark, for making such an awesome book. Even though it’s still in beta, I really recommend this book to anyone who wants to expand their Rails knowledge with bits and pieces of information from major Rails players. Once the ‘full release’ of the book is out in March, I’ll make sure to do a more informative review. For now, don’t be afraid to get this book because it’s tagged as ‘Beta’. That’s far from the truth, it seems.

Respect RSpec

Posted on January 4th, 2008 in Ruby On Rails, Software, Web Development | View Comments

Over the past week and a half, I’ve been busting my ass trying to learn the ropes of Behavior-Driven Development with RSpec. I had been interested in learning either Test-Driven Development or Behavior-Driven Development for quite a while, so I just jumped on one of the two and test the waters out for a while.

I’ve been reading a lot on TDD and BDD for the past couple of months, yet never took the time to implement it to my current projects. The main reason is because I thought it would take me too much time to learn and would bog me down too much, when all I wanted was a workable application running as soon as possible. But, an opportunity presented itself (more on that in the future), so I chose the development technique that seemed better for me: BDD.

Reading about RSpec through other blogs on the Internet, it just seemed so intuitive to use that for testing, I kinda thought it was too good to be true. So after installing RSpec and getting it running on my application, I realized it was true after all. It’s ridiculously easy to write your own tests with RSpec, and it’s almost plain English (just like good ol’ Ruby). It includes built-in stubs and mocks to simulate parts of code, so you can even drop fixtures if you want (although admittedly, a lot of the shortcomings fixtures had were fixed with Rails 2.0). In fact, here’s a simple controller test:

describe ProductsController do

  before(:each) do
    @product = mock_model(Product, :to_param => "1")
    Product.stub!(:find).and_return(@product)
  end

  it "should call the action successfully" do
    get :show, :id => "1"
    response.should be_success
  end

  it "should find the product" do
    Product.should_receive(:find).with("1").and_return(@product)
    get :show, :id => "1"
  end

  it "should assign the found product for the view" do
    get :show, :id => "1"
    assigns[:product].should eql(@product)
  end

end

This test actually works for testing the show action in a controller. I wrote this just to show how readable the code is. I never knew testing would be so readable! And like I said, once you wrap your head around mocks and stubs, it’s ridiculously easy to implement. As a great bonus, RSpec can also integrate with rcov, a tool that actually checks what parts of your code are tested. It’s a great tool for making sure you achieve 100% coverage of your code.

Unfortunately, I didn’t actually do any BDD this time around, as I already had a good chunk of my application up and running already. But now that I have discovered the joys of RSpec, all my upcoming products will be fully done using BDD techniques: I won’t write a line of code until I write the behavioural test before.

A couple of ceveats, though. Hey, nothing’s perfect! First off, if you use different types of plugins for your application, you’ll find some parts of it difficult to test in RSpec. Most plugins use the Ruby’s own Test::Unit testing framework to test their own functionality, but parts in your code where you use these plugins can get you the first time around. Also, if you’re like me, and already have written code for your app, you’ll start finding different ways to fix your code to conform to RSpec testing. This isn’t necessarily a bad thing, as this is most likely a warning sign that you need to refactor that piece of your code anyway. But it’s takes a bit of your time away, so be prepared for this.

In short, RSpec is so easy to use, I don’t see why people shouldn’t use it in their own projects. I suggest every Rails developer should look into RSpec (or any other testing method, really) and stop being lazy. I know I was, but never more!

RSpec References

Ryan Bates from Railscasts has a great screencast that can serve as an intro to testing controllers. And the best part is that it’s free!

* Testing Controllershttp://railscasts.com/episodes/71

Geoffrey Grosenbach over at PeepCode has an excellent three-part series on RSpec, with about three hours of RSpec goodness! No, they’re not free, but the $9.00 per episode is truly worth it. This was my secret weapon in learning RSpec in less than two weeks – The best 27 bucks I’ve spent in my software development career!

* RSpec Basicshttp://peepcode.com/products/rspec-basics
* RSpec Mocks and Modelshttp://peepcode.com/products/rspec-mocks-and-models
* RSpec Controllers and Toolshttp://peepcode.com/products/rspec-controllers-and-tools

Zed Shaw – Exposing the ‘Ghetto’

Posted on January 3rd, 2008 in Open Source, Ruby, Ruby On Rails | View Comments

Before I begin, I just want to wish everyone a Happy New Year! May 2008 bring happiness, peace and prosperity to all.

I’ve been keeping myself very busy lately with RSpec and Behavior-Driven Development, basically learning the ropes and how all the pieces fit together. For now, I’m totally enjoying it. But more on that in a future post.

Now, I know that everyone who read Zed Shaw’s rant towards most of the Ruby and Rails communities will have an opinion on this. But I’ll give my own thoughts on it. All I hope is that someone doesn’t read this and think “Who the hell is this guy to give an opinion?” I might not be a ‘somebody’ in the Ruby or Rails communities at the moment, but I would really like to be part of those communities sometimes in the near future.

Upon first glance, Zed’s rant seems like a completely immature piece, just looking to damage the reputations of certainl people and companies. But if you read closely, ignoring the unprofessional language scattered throughout the text, there’s a whole lot of valid thoughts and reasoning to this entire rant.

Most of his attacks are aimed at two people: Kevin Clark and Dave Thomas. Kevin Clark has been a pretty big part of the Rails community, regularly contributing code and such, and Dave Thomas of course is the author of possibly the most well-known Ruby and Rails books in the market. His story on Kevin is that they possibly never got along and clashed multiple times, while the story on Dave is that supposedly Zed had a fix for a pretty serious bug in Ruby, yet Dave and others ‘threatened’ Zed to not release it. For what reason, it’s not clear in the rant. Now, about these allegations, I don’t know whether they’re true or not (there’s always two sides to a story). But from my own views, I think any environment has these types of problems all the time. My own workplace can be used as personal experience on these manners. There’s always someone who wants to be smarter and better than you, and for some unknown reason they go out of their way to make sure they come out looking better than you can. It’s stupid, but it’s just human nature, I guess. I bet almost any other open-source community is the same.

He also goes on to write about Thoughtworks, a software consulting company that jumped on the Rails bandwagon a while back. Zed’s beef with them is the fact that they charge a shitload of cash while providing not-so-great work in return. Isn’t this is the case with almost all software consultancy places? I can name a few off the top of my head here in Puerto Rico. In fact, all you need to do is go to a website one of these ‘expert software consultants’ made, look at how the site is built, and anyone with an eye for software development standard practices can name a dozen things they would change immediately. This is no surprise here.

I do commend Zed for not making this a 100% negative jab towards Ruby and Rails. He included some people who he knows and have helped him out or were unlike those who he vilified before. Like I said, all communities have their share of bad apples, mostly people who want to be most widely known at your own expense. So the fact that he names some people who were cool to him shows that.

I’ve read a lot of other blogs where people are dismissing Zed for the way he expressed his views, that he burned his bridges and what not. But that’s what he apparently wanted. He said he’s not happy being part of the Rails community, so he wants out. This is his way of getting out. Now, I may not agree with the way he did this at all. You never know when you need to cross a bridge you burned in the past, after all. But being in the position he was, seeing and knowing a lot of things that went down, he has a valid opinion, and he’s simply entitled to it.

I think Zed partly wrote this rant not to bash everyone associated to Ruby or Rails, but to try and help out, in his own way. He knows a lot more about the community than most of us will probably ever know. So hopefully some good comes out of him exposing some dirty details on how the Ruby and Rails world is run. In the end, it simply boils down to this: It’s one man’s opinion. No matter how important he is (or rather, was) to the Rails world, one man isn’t enough to kill it, in my opinion.

Zed, if you miraculously read this, best of luck to you in the future, buddy. Hope the rant was worth it!

At the speed of Rails

Posted on December 20th, 2007 in Open Source, Programming, Ruby, Ruby On Rails | View Comments

I was going to write a small post about Rails and its brand-spankin’ new release, known at version 2.0. But in the time it took to write this, the Rails community not only released Rails 2.0, but also Rails 2.0.1 (thanks to a small error in the original 2.0 release) and 2.0.2 (bug fixes and some nice changes included) were released in short order. That’s part of what I love about the entire Ruby and Rails community: You need to be on your toes and always up-to-date. It may be a pain at times, especially when there’s barely any time for one to do anything at all. But it’s just a blast, and I’m enjoying the ride.

I’ve been using the new Rails features for the past five months now, thanks to access to the Rails Edge code. I really like the direction the framework is taking. RESTful routing is now the norm, multiple views of the same chunk of data are now a breeze, huge security benefits straight out of the box… There’s just too many good things Rails 2.0 has brought out. And the upcoming release of Ruby 1.9 (and its promised speedups) have me anxiously awaiting its arrival. In fact, I’m thinking of porting my Puerto Rican Rails site, RailsPR.com, from the “obsolete” Rails 1.2.3 to benefit from all the changes made by DHH and the rest of the Rails core team. Excellent job, guys. Here’s looking towards the bright, bright future of Ruby and Rails. I’m excited to be part of it.

I want everything!

Posted on October 12th, 2007 in Open Source, Programming, Ruby, Ruby On Rails, Software, Web Development | View Comments

The past two weeks I’ve been totally separated from all of my learning and reading processes I’ve established to myself, and I felt terrible for doing that. It’s not like I’ve been totally disconnected from everything. I’ve still read all my favorite programming-related blogs, as usual. Still, I haven’t just sat down to absorb everything or practice.

These past two days I decided to get back on track. However, I found myself with the same problem I’ve had for a while now. Whenever I sit down to learn something, I want to learn everything. I don’t mean “learn everything of something“. It’s more like “learn something from everything“.

For the past months, I’ve had a hundred different interests. I’m interested in learning Adobe AIR. Microsoft Silverlight sounds like something I could use in the future. I was sold on Test-Driven Development and ever started to adopt its practices to my daily usage, yet recently I’m liking the sound of Behavior-Driven Development more and more and would like to test that road. I want to learn other web frameworks in different programming languages, like Django and CakePHP. And of course, I’m still totally into Ruby and Rails.

I know a lot of people who don’t mind knowing about everything. But the deal is that by learning (or having the desire to learn) about so many things, you don’t fully learn it all. You only learn a bit about each thing, but never a whole lot. There simply isn’t enough time in the world to do so, especially with a full-time schedule. So to say it’s frustrating is an understatement to me.

One technique I’m finding useful to juggle these interests is to create a necessary project in your mind to learn along the way. This should keep your interests level high during the learning process, while making you stay focused with one or two things at a time. For example, my next project is a web application, where I’ll strictly try to use the practices of Behavior-Driven Development while learning to use RSpec. This way, I’ll be learning a lot of different, yet related, subjects at the same time. After this project is done, I’ll see where Adobe AIR has headed, since it’s still in Beta. If it still piques my interest, I’ll create a new project for one of my current needs, and learn from there.

Being in this world of programming and technology, where it seems like time is always on fast-forward, it can be tough to keep up with what you like. But at the same time, it’s just fun. Even though I get frustrated at times, I’m having a ball learning these things. I guess it all boils down to that for now.

RailsPR.com – A Ruby and Rails community for Puerto Rico

Posted on October 1st, 2007 in Open Source, Ruby, Ruby On Rails | View Comments

Note: Unfortunately, I had to take this site offline, due to its inactivity, and due to the fact that I have moved to New York City. I had plans for this site to be a starting point for me to start my own Ruby and Rails User Group in Puerto Rico, but I obviously can’t do that now. Hopefully someone in the near future in Puerto Rico will want to do something similar.

Although I finished this project a while back, I hadn’t announced it anywhere, so here it is. I just finished RailsPR.com, a site which I hope generates some much needed attention to the Ruby programming language and Rails framework here in my native land of Puerto Rico.

The main reason I started this site is because the IT industry in Puerto Rico is currently just centered on Microsoft products. I’ve said in a previous post that I really don’t mind Microsoft, and I think some of their products are great. However, with so many stable and useful open-source alternatives in the market, from operating systems to programming languages, I don’t see why it should be this way.

I’ve been learning and using Ruby for most of this current year, along with Rails. And it still baffled me whenever I talk to other programmers, they don’t even know what Ruby is. They’re still stuck with the same Visual Basic teachings they had in college. There are even some still using COBOL.

So my mission with this site is to create a community where interested programmers from Puerto Rico can be together in one place, sharing their knowledge and experiences, which is really what open-source is all about. It would make me proud to have my site be one of the main reasons people got into Rails.

Capistrano – Like that person you hate, yet end up falling in love with

Posted on September 3rd, 2007 in Open Source, Ruby On Rails, Software | View Comments

One of the reasons I went exploring into Rails was because of Capistrano, a utility that greatly helps deploying Rails sites into production servers, by automating many of the tedious setup steps needed to deploy new changes into production. I know I can’t be the only one who has once or twice pushed some new change into production, only to discover (by myself or an angry user) that I forgot to bring the database schema up-to-date as well. Capistrano (actually, migrations are the key component here) will never allow that to happen again.

In a nutshell, Capistrano does the following:

  • Logs into your server via SSH
  • It creates a directory structure that’s useful in case you want to rollback some bad code you mistakenly pushed unto the server
  • Uses Subversion (or other SCM) to checkout the latest code committed into the repository and downloads it
  • Automatically runs all migrations to make sure the database is up-to-date
  • Runs other scripts, like making sure your FastCGI processes are restarted and running correctly, or restarting your web server

After nearly finishing my first public Rails site (coming soon, I promise!), I wanted to learn how to use this tool by deploying the first version into my VPN space using Capistrano. I thought this would be a daunting task, and at the beginning it was thanks to some minor errors, but after that, it was total bliss. After a few hours of tweaking my settings, I finally got it to work, and all deployments from here on out should be as simple as writing cap deploy without and remorse.

I’m going to write how I set up my deployment environment, so if anyone has had similar problems to mine, they can hopefully get past them.

First off, let me write about my app and server environment:

  • Operating System: CentOS 4.5
  • Webserver: Lighttpd 1.4.15
  • Rails Version: 1.2.3
  • Mongrel: 1.0.1
  • Capistrano: 2.0.0

After installing Capistrano on my development computer (simply using gem install capistrano --include-dependencies), I was ready to “capify” my application. To create the files used for deployment, just issue capify . at the root directory of the Rails application. This creates two files: Capify, which points to the second file, config/deploy.rb, which is the actual deployment configuration file.

The configuration is pretty straight-forward. There are some default settings that can e easily changed to reflect your production server setup. I did just that, and that’s where the ‘gotchas’ started pouring in.

After I changed the default values to my own, I wanted to set up the directory structure in my production server. To do that, simply run cap deploy:setup in the root directory of your application. That should prompt you for your SSH password to create all the directories needed in the directory specified in the deployment file (using the :deploy_to variable). However, when I did that, I got a nice error message: no such file to load — openssl.

After searching a few minutes in Google, I found my problem: I had compiled Ruby from source without the openssl-devel libraries installed in my system. Without the header files, Ruby compiled without OpenSSL support. So after installing the OpenSSL header files and recompiling Ruby (don’t forget to run make clean before recompiling), I was faced with another error message: It stated that my server didn’t exist. Then I remembered I’m running SSH in a non-standard port. Capistrano assumes it’s running on the default port, which is 22. After a few more minutes of searching, I found an option that needed to be added to the deployment file: ssh_options[:port] = xx, where xx is your SSH port number. After these changes, I was golden, as Capistrano asked for my SSH password.

After entering it in and seeing some progress in the directory creation process, I was faced with yet another error message, about a user not existing. I was assuming Capistrano was using the user name from my development box to log into the production server. In any case, this was fixed by adding another option in the deployment file: set :user, "production_user", where production_user is the user name with the appropriate permissions to create the directories and files in the production server. I ran cap deploy:setup once more, and all my directories were created. Success! Little did I know that would be only the first steps, and more troubles were looming ahead.

Once I verified the directory structure was created correctly on my production server, I went ahead and ran cap deploy:cold, which deploys my latest working version to the server, runs all migrations, updates all symlinks to the current code, and runs all remaining processes, like respawning all FastCGI processes, for the very first time. I once again ran into a small snag, as I was having permission problems running some scripts on the production server. After some more minutes of searching, I found that there’s a variable that needs to be set to make sure Capistrano runs the scripts as a specific user with adequate permissions. After adding set :runner, "production_user" (once again, where production_user is the user with the correct permissions to run your application scripts) to my deployment file, I was able to pass the permission parts, but then I hit yet another snag: I was missing a file – script/spin.

I found it odd that Capistrano was looking for this file, as it’s not automatically generated either by Rails or Capistrano. But after calmly reading the Capistrano installation instructions (instead of skimming over most of it), I saw that this file is used to recreate (or create) the FastCGI processes in your production server, to ensure that the users will get served the latest version of your app. There are many different ways to set up your FastCGI processes, depending on what the web server you’ll use. Since I use Lighttpd, I’ll be writing about that here. But you can find tons of useful information on the Internet if you use Apache, nginx or any other web server.

To remedy this problem, all I needed to do was to create the script/spin file (with executable permissions – chmod 0755 script/spin) with the following line (where /root_of_app/ is the path you described in the set :deploy_to: variable in the deployment file):

/root_of_app/current/script/process/spawner -a 127.0.0.1 -i 3 -r 5

This script calls another script called spawner (included in current versions of Rails), which verifies if there are FastCGI processes currently running. If the processes exist, they’re recreated to show the new version of the app. If the processes don’t exist, they’re created. The -a switch indicates the IP address used to direct the FastCGI processes. If you don’t use this switch, it will default to 0.0.0.0, which was causing me problems later on. The -i switch tells the script to create three FastCGI processes in sequential ports. Finally, the -r switch tells the script to verify if these scripts are still active every five seconds. This makes sure that all processes are running smoothly. One switch I didn’t use was the -p switch. By default, the spawner script creates all FastCGI processes starting with port 8000. Using the -p switch, you can specify which is the first port. In my case, the three FastCGI processes are creates using ports 8000, 8001 and 8002. You can change that default if you wish.

After you create the spin script, you’ll need to commit it to your SCM so Capistrano can find it in the production server. Once committed, I re-ran the cap deploy:cold command, and I was greeted with success at the end. My latest version of the application code was sent to the server, all migrations ran, and the spin script created three FastCGI processes on my server. Awesome! My work here with Capistrano was done. After hating Capistrano for a good while, I fixed all the kinks and can now never live without it. I love you, Capistrano.

Feeling good for myself, I immediately fired up my browser and entered my site’s URL. Too bad only 500 – Internal Server Error appeared when I went to the site. Curious, I entered the URL once again, appending :8000 at the end of the URL, and lo-and-behold, the site appeared in all its glory. So the FastCGI processes created with Mongrel were working well. But my web server wasn’t transferring the requests to one of the three processes.

After looking around for more information, I saw how FastCGI processes, Mongrel and Lighttpd work together. In a nutshell, the request for the site is sent to Lighttpd, the web server. Lighty then needs to process this request and send it over to one of the FastCGI processes, which then displays the site on the user’s screen. Lighttpd is simply used in this case as a proxy, and lucky for me, it already has some basic proxy functionality built-in. However, it needs to send the the request somewhere. I saw some tutorials online that set this up, but it seemed to always send the request to only one of the three processes, which wasn’t efficient at all.

Here is where Pound comes into play. Pound is reverse-proxy and load balancer for web servers. Basically, it takes all requests from the web servers and passes it along to the processes running the site, making sure that all processes aren’t over-worked by load-balancing all requests. After installing Pound on my production server, I had to create a configuration file, by default stored in /usr/local/etc/pound.cfg (your location may vary, depending if you compiled and installed the program from source, or just installed a package):


ListenHTTP
Address 127.0.0.1
Port 7999
Service
HeadRequire "Host: .*site.com.*"
BackEnd
Address 127.0.0.1
Port 8000
End
BackEnd
Address 127.0.0.1
Port 8001
End
BackEnd
Address 127.0.0.1
Port 8002
End
End
End

This configuration will make Pound listen to the requests on port 7999 in the local machine (my production server), and forward the site’s requests to one of the three FastCGI processes created by the spawner script I talked about previously. I was surprised at how something so powerful could be easily implemented.

Now all I needed to do was to configure my web server to direct all site requests to Pound, which in turn passed them along to one of the three FastCGI processes. Skipping all the other default settings and changing all sensitive info that may compromise my site, here are my current Lighttpd settings for the site in question:


$HTTP["host"] =~ "(^|.)site.com$" {
server.document-root = "/home/production_user/railsapps/app_name/current/public"
server.error-handler-404 = "/dispatch.fcgi"
server.errorlog = "/var/log/lighttpd/site.error"
accesslog.filename = "/var/log/lighttpd/site.access"
proxy.server = ( "" => ( "site" => ( "host" => "127.0.0.1" , "port" => 7999, "check-local" => "disable" )))
)

Make sure you load the mod_proxy server module so you can use the proxy.server option mentioned above.

Once I restarted Lighttpd, I entered my site’s URL, crossed my fingers, and… success! I finally had a working site, load-balanced and all. What set out to be a learning process in Capistrano in turn made me use load balancing techniques in my site, which was something I planned on doing, but on another day, thinking it was super-complicated.

From here on out, every time I make a change I want to push to my site, all I need to do is run cap deploy on my development box, and that’s it. Everything will be updated with a simple command. It’s truly worth the time I spent getting it to work. Now I will never have an angry user again because I forgot to update the database schema.

In all, I spent a few hours fixing all the small kinks I encountered along the way. But as all good things go, you need to bust your ass to get things working like you want to. I don’t mind at all, as I learned a whole lot in one day. I hope someone finds some solutions in this writeup.

In case you’re curious, here’s my deployment file, with all the sensitive info changed for obvious reasons:


# Application Name - Anything you want to describe your application
set :application, "app_name"
# The URL of your source code repository, pointing to the latest version
set :repository, "http://svn_repo/trunk"
# Set the user name to connect to the server via SSH
set :user, "production_user"
# Set the user name of the user with permissions to run the application scripts
set :runner, "production_user"
# Set the path where you want your application to be stored
set :deploy_to, "/home/production_user/railsapps/#{application}"
# Option to change the SSH port
ssh_options[:port] = xx
# The URL or IP Address where your application will be stored - Multiple sites can be specified
role :app, "xx.xx.xx.xx"
# The URL or IP Address where your application will be served - Multiple sites can be specified
role :web, "xx.xx.xx.xx"
# The URL or IP Address where your database lives - Multiple sites can be specified
role :db, "xx.xx.xx.xx", :primary => true
# Task to restart the web server
task :restart_web_server, :roles => :web do
sudo "/etc/init.d/lighttpd restart"
end
# Restart the web server once the deployment is finished
after "deploy:start", :restart_web_server