Moonshine: What burns blue makes your blues go away
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, Shadow Puppet 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
sudoprivileges that can access your applications’ repository. (Moonshine usesrailsas 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 Shadow Puppet 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!


Comments
Mike Bailey
2009-03-19 at 05:16 AM
Great stuff!
Deprec was originally designed to install a stack that works with the RailsMachine gem. Since then it's grown into something quite different.
I look forward to having a play with Moonshine and think it should be a valuable contribution to the community.
thanks guys!
St Paddy
2009-03-19 at 10:53 AM
It sounds great but doesn't seem much different than Deprec, which is already really quick for doing pretty much the same thing. Is the main difference the auto gem detect/install?
Jesse Newland
2009-03-19 at 03:53 PM
@St Paddy: the big difference is that with Moonshine, ongoing configuration of your servers is be versioned with your app. Want to tweak the InnoDB buffer size? Change a config variable, commit the changes, and deploy and the changes are activated. Moonshine is much more than just initial provisioning - although it does that great as well.
St Paddy
2009-03-19 at 04:19 PM
@Jesse, thanks, didn't catch that. That's a cool feature indeed.
Evan C
2009-03-19 at 04:37 PM
Hi Guys!
Why is Ubuntu 8.10 a requirement? We're running 8.04LTS. 8.10 seems like a strange choice for a production server.
Any chance in getting this running for 8.04? What's preventing it from happening?
Jesse Newland
2009-03-19 at 04:51 PM
@Evan: Ubuntu 8.10 is currently a requirement because that's all we've tested it on. I'm not certain, but I don't think there's anything that shouldn't work on 8.04. Please give it a whirl and let us know how it goes - if you run into any problems, please create a bug in Lighthouse: http://railsmachine.lighthouseapp.com/projects/27287-moonshine/overview
Mike Bailey
2009-03-19 at 10:23 PM
@Jesse Newland: deprec actually generates all configs into the config/ directory of your app to be included under source control.
A point of difference would be the use of Puppet. I'm sure there's a few more too. Will check it out on the weekend.
Guoliang Cao
2009-03-20 at 01:11 PM
This is simply awesome. How are database setup and migration handled? Are there any extra steps to do?
Jesse Newland
2009-03-20 at 02:09 PM
@Guoliang: A MySQL database and user are created from the values in your database.yml. Check out the documentation on the 'rails_bootstrap' recipe for details on how the initial db bootstrap works:
http://railsmachine.github.com/moonshine/classes/Moonshine/Manifest/Rails/Rails.html#M000014
Migrations are automatically run on each deploy.
Henning
2009-03-23 at 10:48 PM
Does the default deploy manifest support deploying to multiple hosts (ie. app, db, memcached roles)? Or would that be a case for developing another moonshine plugin?
Jesse Newland
2009-03-25 at 08:35 PM
@Henning: the default manifest is targeted at a simple one-host deployment. However, it's trivial to execute different manifests on hosts of different roles using Capistrano. We'll be expanding the Moonshine documentation and examples soon, and will be sure to include an example of doing just this.
Genki
2009-03-26 at 03:41 AM
It’s pretty awesome!
But what if I have already installed something like ruby 1.8.7 and mysql, will this plugin work or there will be some conflict?(btw, I've deployed my app on ubuntu before by referring to this guide http://tinyurl.com/bwwygx)
Attila
2009-03-26 at 08:38 AM
Moonshine rocks!
I ran into a question.
I tried to deploy more apps to one server with moonshine. It build REE again all times. Is it supported to have more apps in one server with moonshine?
Eric Berry
2009-03-26 at 03:56 PM
I love you!
Robert Matei
2009-03-31 at 02:41 AM
Seriously fantastic work. I've been trying to settle on an automation solution for my apps for months now and this fell out of the sky at just the right time.
Any chance for an example of how to apply it to different servers? Or the workflow when you add a new app server to an existing cluster? I'm about to go digging through the code, some pointers would be helpful.
Jesse Newland
2009-04-01 at 06:28 PM
@Genki if you edit the :ruby: ree line in config/moonshine.yml to read :ruby: mri, it should work just fine with a pre-existing install of ruby from apt-get. If you compiled ruby custom, just refrain from running the deploy:setup task and install the shadow_puppet gem and you should be fine!
@Attila When setting up a new server, please do the following:
cap deploy:setup HOSTS=rails@yournewhost.com,rails@yournewhost2.com
This will run the deploy:setup task on only the hosts you've specified
@Robert: no documentation on that yet, but checkout this line in the moonshine capistrano recipe. it might get you started:
http://github.com/railsmachine/moonshine/blob/26b3c83920375eedd0782d0b2509f0988b4d4e59/recipes/moonshine_cap.rb#L54
Jason Deppen
2009-04-03 at 03:57 PM
Okay I know I'm probably wrong for not having my repo in GitHub but I don't really want to pay $7/mo when I can keep it locally for free.
What do I need to change this line to:
:repository: git@github.com:username/your_app_name.git
I tried both:
:repository: .
:repository: "."
Here's what I get:
fatal: failed to open /root/./objects
Attila
2009-04-14 at 07:59 AM
@Jesse -
Ok, but what to do if you want to deploy more apps on a single machine?
cap deploy:setup installs REE again and again.(but i need to run it to create the install dirs)
Chris Martin
2009-04-24 at 07:09 AM
@Jesse - This is completely awesome. I might have to build ismoonshineawesome.com just for this.
I am currently deploying to a machine running 8.04LTS, seems to be working well. If it fails I will yell and then fix whatever error _I_ have made.
@Attila - If you are installing onto the same host (single machine) you don't need to run the $deploy:setup step, it's the same for all apps and it is already done (hence the reinstall). Just run a $cap deploy for each additional app you want to deploy onto that machine.
Bob
2009-04-29 at 09:51 PM
Im a n00b in need of a little help.
I had my system running manually, and then cam across moonshine. Since i was having trouble with sphinx and getting it to run correctly, i decided to backup, ipe and redo with moonshine, in hopes there would be some thinking sphinx moonshine very soon.
anyway - im getting this error when deploying
err: /ApplicationManifest#17188760/Exec[rake db:migrate]/returns: change from notrun to 0 failed: rake db:migrate returned 1 instead of 0
When installing manually i needed to go and set permissions on the lib/mysql folder. I did that again with mooshine, but still receive the error..
Any ideas?
thanks for a great plugin.
Bob
2009-04-29 at 09:59 PM
So in the event anyone has the same issue. In my database.yml i had a production password set.
upon removing it, everything ran great.
Bob
2009-04-29 at 10:06 PM
So does anyone have any direction on getting Thinking Sphinx deployed? Thats the problem i originally had, i wasnt quite sure how to write the deployment script?
Anyway, Thanks again. This was my first deploy ever. It took me 4 days manually, but i learned a ton, and with moonshine, i did the same thing in 20 mins..awesome!!
Martin
2009-05-19 at 06:12 AM
Is there a way to avoid entering the SUDO password for user rails during deploy?
I can SSH to my server without a password.
tommy
2009-10-01 at 12:01 AM
is there an option to out of the box select nginx over apache?
Sean
2009-12-30 at 09:23 PM
Hi, can this be used with SVN repo or just git? Thanks you.
Kevin Elliott
2010-01-12 at 07:51 AM
Jesse,
You still working on that documentation and extra manifests you were mentioning in the comments here back in April '09? Would love to see some examples for multiple hosts and roles.
-Kevin
Post a comment