Deploying a Grails app to RackSpace Cloud Servers
Judging from the number of blog articles on the subject, Amazon's EC2 seems to be a pretty popular way of deploying Grails applications. Certainly, the tooling support is good: CloudFoundry provides Cloud Tools, which includes an Amazon EC2 Grails plugin and an Amazon Machine Image (AMI) pre-configured for running Grails; the CloudFoundry service itself makes deployment a breeze; also, if you're a SpringSource Tool Suite user, you can deploy to EC2 from within the IDE.
Despite the good support for Amazon EC2 deployment, there are a few gotchas to complicate matters. Because of the ephemeral nature of EC2 instances, you'll need to use an Elastic Block Storage (EBS) volume to park your database on. Also, if you want a static IP address for your app, your need to configure an EC2 Elastic IP Address. These add to the cost of the deployment, as well as the complexity. Running just one of the smallest available instances with persistent storage 24/7 will cost you just over $60/month.
The easy deployment and horizontal scalability of Amazon EC2 make it a great platform for running you're application once you're in production with a large number of users. However, if you're in the prototyping/early development stages, it's probably overkill. This was the case with a project I'm currently bootstrapping. I was looking for a solution that was simpler and cheaper to use now, but also easy to scale up once the app goes public.
After a bit of research, I decided to take RackSpace's Cloud Server service for a spin. At 3¢/hour (under $22/month) for a Linux server with 512MB RAM and a 30GB disk, and data transfer prices at 22¢/GB in, 8¢/GB out, the price was certainly right. Incredibly, included in this price is 24/7 support by email, phone or live chat.
I found the setup to be quick and painless; my application was up and running on the server within the hour - this includes five minutes spent on the phone on a courtesy call from RackSpace's support team (which was a nice touch!).
I've reproduced the steps from signup to deployment below:
- Sign up for RackSpace Cloud
- Spin up a server instance. You'll need at least 512Mb RAM for Grails. I chose the Debian (Lenny) distro, as setup for this distro is very well documented on the RackSpace wiki.
- Prepare server:
- Lock down your server, following the instructions at http://cloudservers.rackspacecloud.com/index.php/Debian_Lenny_-_Setup
- Install the Java SDK: sudo aptitude install sun-java6-jdk
- Install MySQL: sudo aptitude install mysql-server mysql-client
- Install Grails:
- wget http://dist.codehaus.org/grails/grails-1.2.1.zip, unzip to /usr/share/
- set JAVA_HOME, GRAILS_HOME and PATH in /etc/profile
- While in /etc/profile, you may want to set JAVA_OPTS to give you some more permgen space.
- Create and run a test app to make sure everything is correctly set up.
- Save a snapshot of this server to rollback to in the event of a catastrophe.
- If you need to do some admin to prep your database, I found the best way was to use MySQL Administrator, running on my local machine and connecting to the remote MySQL server through an SSH tunnel. Instructions for doing this from a Windows client using Putty are here: http://realprogrammers.com/how_to/set_up_an_ssh_tunnel_with_putty.html
- You have a number of options for deploying your app, the simplest probably being rsync over SSH. You can do this from your Windows development machine using cwrsync (remember to install rsync on your application server too). An alternative, if you use source control for your project, is to install the source control client on your application server, and export a copy of the project from your code repository. I use Mercurial, so this is as simple as running hg archive <repo URL>, which I execute on the application server via a script on my development machine.

