Monday, November 17, 2008

Small surprise from Git 1.6

After installing Git on my Leopard box I noticed that lots of git-* executables are finally gone in a favor of the single git binary. I like it, as I never liked qmail style of having a separate executable for every operation. By the way, if you're on Mac don't forget turning on bash_completion variant for git-core:

sudo port install git-core +doc +bash_completion

Also set up aliases (git st really saves your fingers), colors and personal data:

git config --global status
git config --global commit
git config --global checkout
git config --global branch
git config --global color.ui auto

git config --global "Your name"
git config --global

Finally, some .bash_profile goodness to track branch in bash prompt (and add colors):

PS1='\[\033[01;32m\]\h\[\033[01;34m\] \w\[\033[31m\]$(__git_ps1 "(%s)") \[\033[01;34m\]$\[\033[00m\] '

Wednesday, November 12, 2008

Rails and Amazon EC2

While we were planning the launch of CookEatShare, a question of the good Rails hosting was heavily discussed. We've been considering MediaTemple, Amazon EC2 and a couple of other solutions (hard to remember right now, potentially Slicehost). Finally we chose EC2.

So after I have a lot of experience deploying to EC2, let's try to answer the question: is Amazon EC2 good for Rails applications?

Ok, first let's see what EC2 is. The official definition is "a web service that provides resizable compute capacity in the cloud. It is designed to make web-scale computing easier for developers." But what does that mean to the application maintainer?

Generally, it's an AWS (Amazon Web Services) account with a couple of associated keys that allow you launch and shut down the instances. You can treat an instance as a physical box with given characteristics with one nuance: if your instance fails (or you terminate it manually) all your data is lost. That is why EC2 is positioned and used more like the platform for streamlined tasks such as video processing or distributed calculations. It may not sound appropriate for the web application, but let's turn to the bright side.

As an advantage, that non-persistence teaches the discipline. When you know that your data will be lost if (I would even say 'when', not 'if') something goes wrong, you'll definitely have backups. And you'll pay more attention to a deployment scheme, especially to ease adding instances later (We didn't scale to the second instance yet but can't wait to try!). And it's fun to have the Capistrano task that builds nginx from source and compiles fair proxy balancer in!

To guard the sensitive data (database, user-uploaded content in case you don't store it on S3), Amazon EBS service can be useful. It's just a block device that can be attached to the instance and mounted as a usual partition. It's persistent and pretty robust, but since we started to use EBS our MySQL server started to behave strangely from time to time. Whether this is Amazon problem or some bug in our configuration, I still don't know. Anyway, I keep trying to fix it.

Instances are pretty stable: previous one worked for almost a year with one hangup that was solved with rebooting) until I manually terminated it after moving to a new one (due deployment change and distribution upgrade).

Disadvantages are not very numerous so far: email rejecting problem (see below), strange EBS behavior with MySQL (again, the real source is still unknown), more effort required to organize the deployment, not all Linux distributions are officially supported, that's all I can remember right now.

So, EC2 can be decent platform for the Rails application deployment. Yet I wouldn't recommend it unless you back it up with the application restore scheme that will allow to operate quickly in case of the instance failure.

Useful facts:

  • if you reboot an instance, the data won't be lost, only the termination leads to the data loss;
  • keeping configuration files (like app server settings, mysql configs, mail server settings) in the application itself is a very good idea. Especially if you need to launch another instance quickly;
  • sending out email from EC2 can be tricky: most servers will reject your email because of blacklisted IPs. This excellent article really helped me set up our mail infrastructure;
  • it's better to start with Elastic IP to make moving from instance to instance seamless, otherwise you will be assigned a dynamic IP that cannot be transferred to another instance.

EC2 solutions:

  • Ubuntu images for EC2 — probably the best Ubuntu AMIs available;
  • EC2 on Rails — very good deployment solution, my own deployment plugin was heavily inspired by this work;
  • Rubber, another decent alternative, it was tricky to follow and I don't need multi-instance setup at the moment, yet it's very interesting;
  • Deployer — my own small solution extracted from CookEatShare. It's not general and I doubt that it works out of the box on the arbitrary instance but I am going to put some care into this product in the future, please fork it if you want to use it and make improvements.