Dr Nic

Closing in on The Dream: “one-click-to-deploy Rails apps”

Got a simple app you want to build? Allocate 5 minutes for initial code generation, slice setup, and initial deployment. All from the command line. In one command. Booya!

How long does it take to start a new Rails project? Surely just a moment? rails new_project -m path/to/some/template.rb

But your application isn’t deployed yet. The DNS isn’t ready, the remote slice doesn’t exist or the config for this new application isn’t setup. Heck, the code hasn’t even been pushed to a non-existent remote repository yet.

And what if you’re going to use something like twitter_auth for authentication? You’ll need to register your application with Twitter at http://twitter.com/oauth_clients.

All these things could be automated, surely. Surely?

If they were then you’d have a “one click” command. A new Rails app, pushed into production, and ready to rock and roll. Complete with either restful_authentication or twitter-based oauth integration.

What does a “one click” rails and deploy command look like?

cd Sites
rails -m rails-templates/mocra.rb default-twitter-auth-app

1. restful_authentication
2. twitter_auth
Which user authentication system? 2

1. mocra-primary
2. mocra-secondary
3. crazy-pron-sites
Install http://default-twitter-auth-app.mocra.com application on which slice? 3^H1

1. drnic
2. mocra
Which twitter user?  1

Then you wait 3 minutes and 53 seconds.

Then you visit http://default-twitter-auth-app.mocra.com and it is working. You click the “Protected” link and you are redirected to Twitter to click the “Allow” link. You return to the app. You are registered with an account and logged in. You see your own face. You rock.

The rest of the article shows you how to test run it yourself, explain the dependencies and how to install them, and how to unit test your own templates to do similarly fancy things. Hopefully its helpful.

WAITING A MINUTE – is this tutorial destructive to my precious slices?

It is safe. IF you have an existing slicehost slice that was created with the latest deprec gem.

Perhaps backup your slice anyway. But it should be safe.

Deprec installs each application in its own folder and the apache settings are in their own file etc. But when deprec installs apache, passenger, etc it may put them in places you aren’t expecting. It might not. I just can’t promise anything.

Testimonial that the tutorial works

Ryan Bigg offers the following testimonial to encourage you to actually try out the tutorial:

“I have, dear readers, with as little effort as a few keystrokes, an an application base that allows my users to sign up using their twitter credentials. I have my code base here on my machine, and the running application in production over there at http://ryan.mocra.com” Ryan Bigg (radar)

Required gems for the template

There are a couple of one-time-only steps to run to install some gems and setup github and slicehost API keys locally.

gem install highline
gem install deprec
gem install defunkt-github --source http://gems.github.com
gem install booster-slicehost-tools --source=http://gems.github.com

To setup the github gem with your API key:

* login to [http://github.com/](http://github.com/)
* click [account](https://github.com/account)
* click "Global Git Config"
* copy and paste the two lines of config into the terminal to install the config

The github gem will now use this configuration automatically.

To setup the slicehost gem with your API key:

slicehost-slice list
Please enter your API key since you did not provide one:

To get your slicehost API:

Required gems and steps for using twitter_auth

My fork of the twitter gem includes a twitter register_oauth ... command. If John integrates the code, or writes his own, I’ll drop my fork and rewrite my template to use his gem. Til then use this one.

gem install drnic-twitter --source=http://gems.github.com
twitter install
twitter add

And enter your twitter account details. You can run the last command any number of times to add personal and corporate/product twitter accounts. I am really impressed with the internals of this gem – it stores your data in a sqlite3 gem and uses ActiveRecord models to retrieve it. Might create a generator for this in newgem. I also liked the use of the main gem for its command definition. Anyway, we’re off the topic.

Cloning and running the rails-templates

Imagine the above steps were “Buy an Xbox 360. Buy Guitar Hero.” Now its the final step. It’s time to rock.

cd ~/Sites
git clone git://github.com/drnic/rails-templates.git
DOMAIN=yourdomain.com ORGANIZATION="Your Company of Legends" rails -m rails-templates/mocra.rb my_app

A few minutes later you can open http://my-app.yourdomain.com in a browser. It will have restful_authentication or twitter oauth integration all setup and working (except email settings for restful_authentication).

It makes me very happy watching it work.

If the above command has stalled after printing ‘executing slicehost-slice list’ then you haven’t set up your slicehost API key. See the instructions above.

Dirty, nasty assumptions?

How can you deploy an entire app and have it up and running without some more configuration? Surely… surely I’ve made some nasty assumptions and come up with some dirty defaults?

Yes.

Your application url will be my-app-name.mocra.com. The subdomain is a dasherized version of your application’s folder name. Use DOMAIN=mycompany.com to change the domain.

Your local and remote database is mysql, accessible with user root and no password. I… look… you see there was this dog… and he ate my homework… it wasn’t me… there was an earthquate, a volcano, a flood… it wasn’t me!

You are deploying to slicehost. I do. It has command-line applications to manage slices and DNS. Since I’m deploying to a subdomain of mocra.com I use slicehost to create a CNAME in the DNS.

Your target slice already exists and has been built using the latest deprec. The template let’s you select an existing slicehost slice to use. If you don’t have one that was built with deprec, perhaps create a new one.

Gems? Plugins? Yes this template installs the ones that I want. That’s the point of rails templates – you create your own set of defaults.

What do I do to get my own uber-template?

Copy + paste the mocra.rb template and hack in your configuration. Fork the github project and push up your file so others can see your awesomeness.

See the section on unit testing templates too.

What’s missing?

The primary thing that I want that I haven’t gotten around to writing/fixing/finding a solution is the creation of private, company github projects. That is, instead of public/open-source, personal projects using github create-from-local.

I guess I would want a github create-from-local --private flag to create a private repo instead of a public repo.

Then I’d want the github gem to know that I live in a world of multiple github accounts: my personal account (drnic) and my company’s account (mocra). That is, I’ll want new private company projects to go on the company account.

And then I’ll want it to add me (drnic) as a collaborator. Or a whole group of people.

Since the github gem currently derives its user + API token information from your global git config (git config --get github.user), instead of a nice external sqlite3 database like the twitter gem, I’m not sure what the best/correct data structure would be to add multiple user support to the github gem.

Or perhaps the github create-from-local mechanism should be extracted out of the github gem all together into a github-admin gem which would have multiple users, create public/private repos, add collaborators etc. Yeah, that might be better.

Want a default application theme?

The template will attempt to invoke a generator app_layout if it can find it. Watch the railscast on generators for an example of how to create a local generator and he gives an example of creating a default application theme generator. That’s why all the railscasts applications look the same!

Bonus section: unit testing a Rails template

If you look in the rails-templates project you cloned you’ll see a spec folder. There is a mock template_runner.rb which is used by the spec/mocra/template_spec.rb. This way I can stub out calls to command-line tools like slicehost-slice list and twitter register_oauth and check that the template installs the correct plugins, creates the correct files, etc without actually installing or creating anything.

More importantly its a lot bloody faster to run than the full template.

If you’re creating Rails templates with interesting logic in them then writing some unit tests for your template might be a helpful idea to save time.

Related posts:

  1. Instant new Rails applications with the App Scrolls When I start a new project I want to start...
  2. Using CoffeeScript in Rails and even on Heroku I’m pretty excited about CoffeeScript as a clean-syntax replacement for...
  3. Dead simple JavaScript Unit Testing in Rails Formats: Video/Screencast (410 Mb, torrent) | Video only (vimeo)...
  4. First look at rails 3.0.pre This article is out of date in some aspects....
  5. Rails themes can remember things I was getting annoyed at having to remember all the...

13 Responses to “Closing in on The Dream: “one-click-to-deploy Rails apps””

  1. Charlie Park says:

    Thanks so much for this post. Working through it now.

    For what it’s worth, I had to also run …

    gem install uhlenbrock-slicehost-tools

    … when I was getting the Slicehost setup step going. Without that, it wasn’t recognizing the slicehost-slice command.

  2. Dr Nic says:

    @Charlie – the instructions included gem install booster-slicehost-tools – that didn’t work for you? I must I’ve had both installed on my machine over the weekend (the booster one includes a fix to the slicehost-slice add command released today); but they should be mostly the same afaik.

    Thanks anyway for the comment!

  3. So this uses github for its git repository? Do you think it would be possible to have a git repository created on the new slice and to use that?

    I’ll definitely give this a test when I get time. It’s great to have more options other than deprec. The whole server provisioning aspect of rails seems to be getting a lot of love from various people at the moment and it’s good to see as it can definitely be a big headache for developers.

    Thanks for putting the time in and for releasing this.

  4. Charlie Park says:

    @Dr Nic -

    For some reason, it didn’t include the uhlenbrock bit. It *did* include wycats-thor-0.9.8 when I ran gem install booster-slicehost-tools. But until I got the uhlenbrock in there, it just returned -bash: slicehost-slice: command not found.

  5. Dr Nic says:

    @Anton since its ultimately just a recipe/template you can/should copy + paste it into your own and then insert your preferred deprec-alternative to get everything up and running. Or instead of mysql you could add in a postgresql database.yml etc (the only reason my script generates its own database.yml is that the default rails one includes sock config which is invalid on a deprec installed slice).

    Let me know if you get thru the tutorial and get some simple twitter-auth apps up and running! I’ll add any “testimonials” into the article above.

  6. Dr Nic says:

    @Charlie – hmm, I’m having no luck reproducing that problem. I uninstalled both slicehost-tools gems and thor, then reinstalled booster-slicehost-tools and slicehost-slice list worked.

  7. Matt Conway says:

    If you’re looking for something similar for deploying to ec2, I’ve written a capistrano extension that makes it fairly easy: http://wiki.github.com/wr0ngway/rubber

    The major benefit of this framework is that its pretty easy to get up and running, yet scaling up to multiple instances requires very little additional effort.

    I’m currently using it to manage 20+ instances for my dayjob, and I know a number of other consultants find it useful for firing up new setups for their clients.

  8. Brian M says:

    Hi Dr. Nic,

    I’m having trouble parsing the 3-line block of commands that begins with “cd ~/Sites”. Did it word wrap in the wrong places? I don’t understand how a command would start with DOMAIN= and then have “rails -m” in the middle.

    Thanks.

  9. Dr Nic says:

    @Brian – this is correct; the DOMAIN=xxx.com is setting an environment variable to override some defaults. You might prefer to just create your own template and change the defaults for yourself.

  10. DanNewman says:

    get to the point of runnint twitter cmds …and get thie error:

    can’t activate activesupport (= 2.3.1, runtime), already activated activesupport-2.3.2 (Gem::Exception)

    very cool stuff… here looking forward to getting it working.

  11. Dr Nic says:

    @Dan – hmm, the ever-unhelpful activation attempts of two gems. Hard to debug the cause and often an irrelevant error.

    If you don’t need activesupport 2.3.1 then uninstall it (and all the rails 2.3.1 gems) as they have been patched in 2.3.2

  12. Melvin Ram says:

    Hey Dr. Nic,

    Here’s a different approach to deployment using Moonshine: http://railsnotes.com/161-rails-server-setup/

    Overall, from start to deployment takes me about 15minutes so it’s fairly painless. In the article I do only focus on server setup & deployment… so the authentication stuff will need to be done using a Rails template or something.

    PS: Say hi to Radar for me.

    ~ mel

  13. Dr Nic says:

    @Melvin – in my rails-template I’ve now extracted the deploy.rb script out into a local “deploy” rails generator which creates a fully-functional Capfile (for me) with my deprec + github settings. These could be changed to any other setup nicely here. I guess you’d remove the slicehost setup too.