This week’s Ruby Weekly was sponsored by AppFog. It sounded interesting so I thought I would give it a whirl. Their pricing model is interesting - it is based on how much RAM you use (free if you use less than 2 GB!). Seems sensible to me since that is what I have usually found to be the limiting factor for the kinds of sites I run. And I’ll have to say that their “Jumpstart” setup couldn’t have been easier - two clicks and a name for the app and I had a Rails app running in the cloud in well under 2 minutes. Of course all it does is show the “Welcome to Rails” page we all know and love. So now how do I make this useful?
If I were not a document-reading sort of person, it would have taken me less time to figure things out. When you are logged in, your AppFog console page is a list of your apps. Clicking on the app name gets you to “Mission Control” for the app and one of the tabs on that interface is “Update Source Code”. That page provides the details about how to install the ‘af’ command-line tool that were missing from the AF CLI doc page I had looked at first. It confirmed my suspicions that ‘af’ was distributed as a gem (even though all the docs did was link to the GitHub repository). I will probably want to use this for more than one project, so I’ll want ‘af’ available in all my gemsets. So I did:
$ rvm gemset use global $ gem install af Successfully installed json_pure-1.6.7 Successfully installed rubyzip-0.9.9 Successfully installed mime-types-1.19 Successfully installed rest-client-1.6.7 Successfully installed terminal-table-1.4.5 Successfully installed interact-0.4.6 Successfully installed addressable-2.2.8 Successfully installed uuidtools-2.1.3 Successfully installed rb-readline-0.4.2 Successfully installed af-0.3.18.2
Once past that hurdle, things look better:
$ af login $ af apps +-------------+----+---------+--------------+-----------------+----+ | Application | # | Health | URLS | Services | In | +-------------+----+---------+--------------+-----------------+----+ | cnk | 1 | RUNNING | cnk.rs.af.cm | cnk-mysql-29232 | rs | +-------------+----+---------+--------------+-----------------+----+
OK now for that documentation on actually using the tool.
I actually ended up using a combination of methods. I used the “Download Source Code” button on the web interface to get a copy of the generated code that is on my running site. I swapped out the “Welcome to Rails” page for my boring test message and then used ‘af’ to redeploy the new code:
$ af update cnk --path appfog-test af update cnk --path appfog-test Uploading Application: Checking for available resources: OK Packing application: OK Uploading (38K): OK Push Status: OK Stopping Application 'cnk': OK Staging Application 'cnk': OK Starting Application 'cnk': OK
One odd thing, I couldn’t run any ‘af’ commands if I was in the directory of Rails code I downloaded from AppFog. Any ‘af’ subcommand I tried errors with:
$ af apps af apps /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/bundler-1.1.4/lib/bundler/spec_set.rb:90:in `block in materialize: Could not find multi_json-1.3.6 in any of the sources (Bundler::GemNotFound) from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/bundler-1.1.4/lib/bundler/spec_set.rb:83:in `map!' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/bundler-1.1.4/lib/bundler/spec_set.rb:83:in `materialize' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/bundler-1.1.4/lib/bundler/definition.rb:127:in `specs' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/bundler-1.1.4/lib/bundler/environment.rb:27:in `specs' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/rubygems-bundler-1.0.3/lib/rubygems-bundler/noexec.rb:41: in `candidate?' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/rubygems-bundler-1.0.3/lib/rubygems-bundler/noexec.rb:60:in `setup' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/gems/rubygems-bundler-1.0.3/lib/rubygems-bundler/noexec.rb:75:in `<top (required)>' from /Users/cnk/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `require' from /Users/cnk/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:60:in `rescue in require' from /Users/cnk/.rvm/rubies/ruby-1.9.3-p194/lib/ruby/site_ruby/1.9.1/rubygems/custom_require.rb:35:in `require' from /Users/cnk/.rvm/gems/ruby-1.9.3-p194@global/bin/ruby_noexec_wrapper:9:in `<main>'
I think for now I’ll ignore that problem.
Overall, this is vary clean and neat. One thing I already miss just a little is Heroku’s git-based deploy strategy. Being the version control junkie I am, there is something so right and satisfying in deploying with ‘git push heroku master’. So can you use git to deploy to AppFog? Apparently yes. It is a little more involved - you have to run a Node.js app that you can use as the url for a git post-receive hook. That let’s you automatically deploy whenever you push to the prodution (or whatever) branch.
Heroku also has some very convenient tools for moving data to and from your production database (using the taps gem). The equivalent thing in AppFog appears to involve ssh-tunnelling - see this post for details.
So far AppFog is looking promising. For most of what I do Heroke is amazingly convenient - and it now supports stacks other than Ruby on Rails. But one thing I noticed listed in the AppFog Jumpstart lists is Drupal. I am not sure if Heroku supports Drupal or not - but if I need a Drupal site and need more control than one can get hosting at Drupal Gardens, AppFog might be an option.