Closing in on The Dream: “one-click-to-deploy Rails apps”
Tháng Tư 1, 2009
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:
Please enter your API key since you did not provide one:
To get your slicehost API:
- login to https://manage.slicehost.com
- click “Account”
- click API Access
- click “Enable API Access”
- copy + paste the API Password into the terminal above
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?
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.
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
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.