This is a second post in my startup series (first one). Warning, this one is a lot more technical than my first one.
If you have been following my blog, my company or my twitter page then you probably know that my startup – yonkly – was built with ASP.NET MVC. In this post, I will talk about how I scale deploy Yonkly very easily.
Initially, I had it hosted on Amazon Web Services inside EC2 instance. That didn’t work too well for a few reasons:
- EC2 only supports windows 2003
- A separate instance is needed for load balancing (extra cost)
- The database instance is very costly
- Databases tend to run slow on virtual machines
While looking for alternatives to AWS, I joined Microsoft BizSpark (a program that provides software, support and visibility for software startups). The greatest benefit of the program is the use of pretty much all Microsoft products for 3 years for free. Imagine all the SQL and Windows licenses that you need to scale your website – all for free. Another great benefit is that Microsoft partnered with hosting companies for even more discounts.
The next step is to find a hosting company. I went with ServePath/GoGrid. They offer the best combination in price, scalability and flexibility. I got a dedicated server for SQL Server and created virtual machines for the front end in GoGrid. Since both services are by the same company, the virtual machine has a super fast connection to the dedicated server. The cool thing about GoGrid is that it includes a free load balancer. So my setup looks something like this:
The blue machines are virtual/cloud machines running in GoGrid and the database server is a dedicated/physical server.
Web Servers: Windows 2008, IIS, ASP.NET MVC
Build Server: Windows 2008, TeamCity
Database Server: Windows 2008, SQL Server 2008
The beauty of all this is that I can add X more servers and scale within minutes. Eventually, the db server will be the bottleneck and I would have to cluster it, but let’s not get ahead of ourselves here.
Management & Deployment
You are probably wondering. How do you manage all these machines? How long does it take you to deploy a new version? The answers are “easy” and “less than a minute”
I started off using CruiseControl.NET (CCNET) to manage my build and deployment but eventually changed to TeamCity. I like CCNET and the fact that is written in .NET and runs in IIS is very comforting to me. On the other hand TeamCity is way more capable, has a better interface and was way too easy to setup. On the flip side, TeamCity is written in Java and runs in Tomcat. This is a very simplified list of benefits, for more info check their homepage and look at the screen tour. The best part, both products are free and CCNET is open source.
Once I got TeamCity up and running, I created 2 projects one called “Yonkly Build” and the other “Yonkly Deploy”.
The Yonkly Build project:
- monitors the source control repository (SVN)
- checks out changes
- builds the code
The Yonkly Deploy project copies the changed files using Robocopy to every web server using a NANT script. The NANT build file looks like this:
You can repeat the Robocopy command for every web server. You can learn more about Robocopy here, NANT tasks here and the exec task here. The fail element in the above XML file tells TeamCity to only fail the build if the return value from Robocopy is greater than 7. Get more info about Robcopy return code which is a bit map over here.
It’s important to note that I have a dependency setup between my build and deploy projects. This is to ensure that I don’t deploy a failed build. The deploy project will only work if the build succeeds.
Tools & Helpers
There are a couple of helpful tools/plugins that make TeamCity even more powerful. The first plugin is a system tray notifier that will display popups to notify of build status.
The other plugin is for Visual Studio and is a “killer feature” for TeamCity. It allows me to verify that my code will build on the server before I check it in. it’s probably better if you read the description on their site.
Ready. Set. Go
Now, all I have to do is check in my code. TeamCity will detect the new files, check them out, build the application and if it succeeds, it will deploy it.
Many of these things are relatively new to me, so if you know of a better way to do things, please share. I am also looking for a way to automate my database migration (probably with a NANT task).