Skip to main content

Nerddinner on Appharbor

My last exercise on deploying Nerddinner on IronFoundry helped me a lot to understand the platforms capabilities. Time to do the same thing on AppHarbor, another PaaS player in .Net space. AppHarbor tries to emulate Heroku in .Net space. They are the 'Azure done right ' brigade.

As a developer I just needs to push code either to AppHarbor or some of the supported repositories such as CodePlex, GitHub, BitBucket and AppHarbor does the rest. AppHarbor
  • Builds the code.
  • Runs unit tests
  • Deploys the application on AppHarbor’s application servers (backed by Amazon EC2).

Other than that it also provides all the standard benefits as provided by most PaaS players.
To gain first hand experience on AppHarbor I decided to port Nerddinner onto AppHarbor. I already had the Nerddinner codebase in github so i could start right away.

Creating Account 
The first step was to register my account with AppHarbor. Once registration is complete we get a single instance under the free tier. That was good enough for me to complete this exercise.

Linking to Repository 
To use the AppHarbor infrastructure I had to link my github project with my AppHarbor account.

The first step here is to create an application from the AppHarbor dashboard.

Then link that application with the code repository (github in my case). I would not detail this process here as details are already available on AppHarbor. Things to note here are
In my case since I was using my public github repository, hence went ahead and configured the link between my github repo and AppHarbor.

Deploying the Application 
This is where AppHarbor shines.

I made some changes to my app on the local clone and pushed the changes to my remote github repository.

I went back to my dashboard on AppHarbor and I could see the application being built.
It failed for me for the first time due to some missing file but I was able to fix is promptly.
AppHarbor makes the build logs available for every build performed. These logs can come in handy while debugging the build failures.
I did a remote push again and the build kicked it again, this time succeeding. I fired the browser and navigated to the application http://nerddinner-4.apphb.com to verify the deployment. Nerddinner was up and running.

Not it was time for database integration.

Database Deployment
Nerddinner requires SQL Server to store its data and therefore I had to provision a SQL Server instance in AppHarbor.

AppHarbor provides free shared SQL Server instance add-on with 20 MB storage. That was enough for me to get started. I provisioned my SQL Server from AppHarbor addon page 

Once provisioned the next step was to get the details of the new SQL Server instance. These details can be easily retrieved from the application dashboard. More details are available later in the post.

Since AppHarbor SQL Server instance is exposed to internet, I was able to connect to it from SQL Management Studio and execute the scripts for Nerddinner and aspnet DB (part of code-base).

Database was ready, application was up and running. Now was the time to link these two pieces

Linking Database to Application 
In AppHarbor this linkage is achieved through Configuration Variables (CV). CV are variable defined for each application in AppHarbor. Once defined the variable names are matched with appsettings key names in configuration file (web.config) and value replacement done during deployment.

The following Configuration Variables are created automatically when SQL Server instance is provisioned








Variable SQLSERVER_CONNECTION_STRING_ALIAS is of interest to us. The value of this variable determines which connectionstring (in our config file) would be replaced by the value of variable SQLSERVER_CONNECTION_STRING

Nerddinner config file has two connection strings 'NerdDinners' and 'ApplicationServices'. Since I had just one database and just one variable replacement available I had to ignore one of the connection string ('ApplicationServices' in this case).

I achieved this using Config transformations. Since AppHarbor builds the solution in Release mode (currently no other mode supported) and also supports configuration transformations. I updated web.release.config with the correct transformations.

On AppHarbor front I had to set the SQLSERVER_CONNECTION_STRING_ALIAS value to ‘NerdDinners’ to achieve the desired linkage.  The above variable is not directly editable from the Configuration Variables interface and requires one to dwell into the SQL Server add-on configuration. 

Here is how this is done

  • Go to the application dashboard and click “SQL Server” add-on link


  • Click ‘Go to SQL Server’ link on the subsequent page.








  • This brings up the details for the provisioned SQL Server. Here we can change the alias









Once I had changed my alias, I pushed my config changes to remote repository and automatic build process kicked in. The site was updated within a matter of seconds and I had a fully functional Nerddinner up and running.

The site is available here http://nerddinner-4.apphb.com/ The code base is available here https://github.com/chandermani/NerdDinner70027

Final Thought

I recently deployed Nerddinner on IronFoundry, and now on AppHarbor. If you look at developer friendliness, AppHarbor wins hands down. The integration with code repository, easy\fast deployment, add-on services are some of the highlights of AppHarbor. Its deployment model is much superior to Windows Azure and Azure team can take some learning out of AppHarbor experience.

AppHarbor provides its infrastructure on per month rather than per hour billing. The same is true for AppHarbor add-ons too.

Update: As Rune commented  'AppHarbor actually prorates the monthly infrastructure and add-on prices down to the millisecond, so you only pay for the time you use it (even more fine-grained than EC2) '

IronFoundry still is in its nascent stage and a direct comparison would be unfair. Since IronFoundry is open source there is an opportunity to incorporate the good parts of AppHarbor and Windows Azure into IronFoundry platform.

Comments

Popular posts from this blog

Caching Images downloaded from web on Windows Phone Isolated storage

I was helping on a Windows Phone application where the requirement was to cache the images the phone downloads on the isolated storage for offline viewing. I wanted a solution which was simple and as transparent as possible. While researching I found  someone wrote a Silverlight converter for loading images from isolated storage. Taking that as a base I created a converted which can Load image from web (http + https), and persist it to isolated storage. In case of network connectivity issues can load the same image from isolated storage. It does that by mapping the http url to a isolated storage location. In case the network is down and the image is neither there in cache, loads a default image, passed as parameter to converter. Here is the gist for the implementation. To use the converter Import the name space. Declare the converter as resource. Set the Image Source Property to use this converter like this 

Integrating ASP.Net MVC with AngularJS

We recently released a Project Template for ASP.Net MVC and AngularJS here and here . I did a follow up post detailing how the project template has been setup and how to make AngularJS and MVC play well together on my company blog . If you are interested in understanding how the template works head over to my blog post and read it!

IIS Url Rewrite and HTTP POST data

If you play around with IIS Url Rewriting rules and try to do redirects on an HTTP POST you loose your POST data. To make sure you get the post data you have to set the `redirectType` to `Temporary` within your rules. So the action configuration looks like this <action redirectType=" Temporary " type="Redirect" url="http://{HTTP_HOST}{REQUEST_URI}"> </action> You may think what scenario warrant a POST request redirect. We faced one such scenario while doing SSO with a federated Identity Provider (IP)  such as Google, Azure AD. In federated authentication scenario once the user is authenticated by the IP, it redirects back to your site with claim tokens in a POST request over secure channel (https). In our case we wanted to redirect to user back http after receiving the request. But any redirects were causing loss of token. By doing a 307 (Temporary) redirect we were able to preserve the post data.