A Quick Look At AppHarbor


As mentioned in some earlier posts, I’ve been hacking on Shopify for the past six months for an e-commerce project. My work with Shopify introduced me to Heroku, which is a simple “cloud-based” service for hosting and running Ruby applications. It’s dead simple to get started and, for the most part, seems to “just work”.

While I enjoy playing with new languages and platforms, I’m by no means a Ruby developer. Heroku is a great service, but seemed somewhat inaccessible to me given that I’d have to work with an unfamiliar language in order to use it. It seems that Microsoft’s Azure platform is trying to fill this same niche for .NET developers, but my (admittedly limited) experiences with Azure have been far from smooth.

When I heard AppHarbor being referred to as a “Heroku For .NET / Azure Done Right” I headed over to their site and signed up for an account right away. I’ve been playing around with it for the past several days to see if it lives up to the hype. In short: I’m pretty impressed with what I’ve seen so far. This post outlines some of my initial findings.

Setup

The AppHarbor site is fairly minimalist in its design, which makes it very easy to get started. Upon landing on their home page visitors are immediately greeted with the message: “.NET Deployment Done Right … git push appharbor master”. Awesome.

If you’ve used a service like github before then getting up and running on AppHarbor will feel very natural. If you’ve never used github or git before it’ll take a minute to grok, but is completely worth it. For the rest of this post I’ll assume at least a basic familiarity with using git and the concept of remote repositories. There are tons of excellent resources out there for learning about git (I recommend the TekPub git series), so I won’t bother repeating that information here.

After signing up for a free account, head over to the msysgit project page to grab the latest and greatest version. I use git for some side projects and had a few issues trying to push to AppHarbor initially that were cleared up after upgrading to the latest version.

Creating And Deploying a ‘Hello World’ Application

Since I was digging into a new hosting platform I decided to go ahead and dig into the latest MVC 3 bits at the same time. The Web Platform Installer got me everything that I needed and I had a new boiler plate MVC 3 application up and running locally within a few minutes.

From here, initialize a new git repo in the solution folder where this solution and web project live. AppHarbor requires that the code you push to them contains a single solution file with a single web project (note that you can have other class library projects within that same solution for encapsulating code). I do most of my development this way so this approach is fine with me, but I did notice at least one thread in their support forum asking for multi-solution support. If I were them, this wouldn’t be at the top of my priority list for new features, so I have a feeling the single solution approach is probably going to stick for awhile.

Once you’ve initialized the git repo, added all of your files, and committed them to your local master repo, you’re ready to setup things on the AppHarbor side. Log into your AppHarbor account and go to the ‘Applications’ screen. Creating a new application is as easy as providing an application name. After creating the application you’re provided with a few quick steps for getting your code deployed and running in the AppHarbor environment.

Jump back into git and run the following command against your local master repo to create AppHarbor as a remote repository for your application (note that the git endpoint for your application can be found on the application details screen in AppHarbor):

git remote add appharbor <your application endpoint>

Now, deploying your application is as easy as:

git push appharbor master

You’ll be prompted for a password (which is the same as your AppHarbor account password) and provided with a status message informing you that your application has been queued for building. If you check the application page in AppHarbor you’ll be able to check on the status of the build:

image

When the build completes successfully, the code is automatically deployed and available to be run at your application’s URL (http://<app_name>.apphb.com).

You can view past builds and deployments and even choose to deploy an earlier build at any time, though if you had a database attached to your application that quick rollback could have some adverse side effects.

You can also view the details of each build and even get detailed console output to troubleshoot issues if they arise.

Environment Specifics

If you’re like me, you prefer having your entire development stack run locally when doing development work. This means that you like having your IDE, light-weight web server, and database all play nicely together on your development machine when you’re cranking out new features. This is great, but the configuration you use when developing locally is almost never the same configuration you need when the application is being used or tested by others.

AppHarbor has a built-in mechanism for allowing your code to determine which environment it’s running in and change configuration settings accordingly. All you have to do is add the following line to the ‘appSettings’ section of your web.config file:

<add key=”Environment” value=”Debug”/>

After you deploy your application, this value is automatically set to the value “Release”. Similarly, you can add the same line to the app.config file in your unit test project and it will have it’s value set to “Test” while AppHarbor runs your unit tests (more on that in the next section).

In the past I’ve maintained separate configuration files for each environment I work with and had my build process choose the right file for the environment being targeted. I don’t currently see any way to make that work with AppHarbor, so in a future post I’ll be digging into some potential alternatives. I’m thinking about defining a separate assembly in my solution that will be responsible for managing all of the various environment specific configuration values (e.g. connection strings) and return the proper value to the calling code based on the ‘environment’ value found in the main configuration file.

Unit Tests

Outside of being able to use git to deploy my applications, the other thing that really piqued my interest in AppHarbor is their ability to automatically run unit tests immediately following each build prior to deploying the application.

To make use of this feature, all you need to do is add a unit test project to your application and reference one of the supported unit test framework libraries. As of this writing, recent versions of nUnit and xUnit were supported.

AppHarbor finds these references and automatically runs all of the tests contained in those assemblies prior to deploying your code. If all of the tests pass, the code is automatically deployed. If one or more tests failed, the application remains on the last successful build.

image

Potential

While I’ve really only scratched the surface, I see a lot of potential for AppHarbor as a hosting platform. I love their convention-based approach to hosting and deploying applications: one solution with a web project, automatically running tests for any assembly that references a test framework, automatically grabbing and changing the ‘Environment’ application setting, etc. These conventions make it very easy to get up and running. Furthermore, these are all conventions that, for the most part, make a lot of sense. I haven’t seen anything about AppHarbor that would force you to write your application in a way that would prevent it from being run on a dedicated, semi-dedicated, virtual, or shared hosting environment with no changes. To me, that makes choosing this platform a lot more attractive than some of the alternatives out there. I plan on digging in a bit deeper in a future post to explore some more advanced concerns like file system storage (if that’s even an option), working with databases, and session state.