We’re happy to announce the release of Moonshine, the system we’re using to make the deployment and configuration management of our new customers’ Rails applications a no brainier. Moonshine combines all of the good parts of Puppet, ShadowPuppet and Capistrano into an amazingly simple solution for deploying your Rails application.
Look at all the choices I’m not making
One of the things that separates Moonshine from other solutions like Chef and Sprinkle is that out of the box, Moonshine comes with recipes for the same Ubuntu/Ruby Enterprise Edition/Apache/Passenger/MySQL stack that’s in production use at Rails Machine. We’re open sourcing this stack as a part of Moonshine for a couple reasons:
- To make it easier for Rails developers to deploy an application to any host, not just Rails Machine.
- To allow our customers to have a say in what they want in a Rails stack. If there’s something missing or a choice we’ve made that you don’t agree with, fork Moonshine, make your changes, and send us a pull request.
Since Rails Machine was founded in 2006, we’ve been dedicated to making the deployment of Rails applications easier for our customers. With the release of Moonshine, we’re taking that one step further by making Rails application deployment and configuration management easier for everyone!
So, how do I get started?
Moonshine is distributed as a Rails plugin. To get started with Moonshine, install this plugin and run the included generator:
ruby script/plugin install git://github.com/railsmachine/moonshine.git
ruby script/generate moonshine
You’ll notice a couple new files:
app/manifests/application_manifest.rb
config/moonshine.yml
The first file is the Moonshine::Manifest
for your application. A Moonshine
Manifest is a Ruby class that contains ShadowPuppet recipes – essentially
just instance methods – that install packages, create configuration files, and
run system commands. The manifest that’s been generated for your application
is actually subclass of Moonshine::Manifest::Rails
, which contains the
entire Rails Machine production stack as recipes.
The second file is a hash serialized to YAML that contains the configuration
for your application’s deployment. You’ll notice that this file contains
variables you may be used to configuring in Capistrano – the location of your
source code repository, the user to execute commands on the server as, and the
deploy_to
location on your server. Configure these just as you would in
Capistrano – this configuration hash will be available to both Capistrano and
Moonshine.
If your application doesn’t have any requirements in addition to the gems
specified in your config/environment.rb
(you have specified all of your gem
requirements using config.gem
calls, right? If not, stop reading and do this
now), then you’re ready to deploy your app!
Deploying your Application with Moonshine
Once you’ve installed the Moonshine plugin, generated a manifest, configured Moonshine, and committed all of these changes to your repo, you’re ready to deploy! To work with Moonshine, your server needs to satisfy these requirements:
- Ubuntu 8.10
- Has a user with
sudo
privileges that can access your applications’ repository. (Moonshine usesrails
as the default user – this is configurable inconfig/moonshine.yml
)
This server doesn’t need Ruby, MySQL, or anything installed on it. That’s what Moonshine is for!
Once your server has been provisioned, capify
your application and replace
the stock config/deploy.rb
with this one-liner:
server "myubuntuserver.com", :app, :web, :db, :primary => true
Once that’s in place, run the following command:
cap deploy:setup deploy
First, in the deploy:setup
task, Moonshine will install Ruby Enterprise Edition, Git, and ShadowPuppet and setup your
deploy_to
directory. What happens next, during the deploy
task, is what
makes Moonshine so awesome.
On the first deploy of your application, all requirements defined by recipes
are installed, configuration files are created, and services started. In
repeated tests on a Ubuntu 8.10 server running in VMWare, this first deploy
takes between 10-15 minutes to install everything needed for a Rails
application. You read that right – less than 15 minutes after running cap
deploy:setup deploy
on a stock Ubuntu 8.10 server, your Rails app will be up
and running.
Idempotent Deployment
On each and every deploy of your Rails application, your Moonshine Manifest is applied and verified. This means no more failed deploys because of a missing gem or package, and more importantly, you’ll never have to SSH to your server to install a package again.
For example, say you have a Rails app in production using Moonshine and you’ve
added file uploading using
Paperclip. After adding a
config.gems 'paperclip'
line to config/environment.rb
, run rake
moonshine:gems
to cache your gem dependencies, commit the changes to your
repo, and then deploy. Moonshine will automatically install Paperclip and
ImageMagick (!!!) during the deploy. Done. Awesome, right?
Brew Your Own
So the default Rails stack we’ve included is just the tip of the iceberg. As
we use Moonshine more and more at Rails Machine, we’ll be adding built in
support for things like Memcached to the recipes in
Moonshine::Manifest::Rails
. And the plugin support in Moonshine makes it
ridiculously easy for you to create reusable of recipes to share between apps,
or even to include Moonshine recipes as a part of your plugin! If none of you
beat me to it, I’ll be forking Thinking Sphinx and pouring some Moonshine on it pretty soon.
Use the Source, Luke
So what are you waiting for? The source and RDocs are up on GitHub – go nuts.
Moonshine at Rails Machine
Moonshine is currently available for all customers of our Application Management services at Rails Machine. If you’re an existing customer on a CentOS server and are interested in using Moonshine without the expert management, 24/7 monitoring, and proactive support that comes with our Application Management services, you will be able to redeploy to a new Ubuntu-based system very soon. Stay tuned!