One of the most important tasks in the software development cycle is the task of application deployment. Whether it is a web application, console application, or service, the application will have to be deployed to the production environment at some point in its life. Deployment techniques vary a lot and are more often than not done by hand or in an insecure manner.

When the project grows and multiple instances of machines are added to support its increasing needs, it becomes painful to manage deployment process manually. Thus, this post will help you understand how to automate your .NET website deployment and relieve some of the stress that it induces when done manually. You will also be able to deploy your application reliably in a matter of minutes, without copy-pasting anything. Besides that, you won’t have to worry about adding additional servers or a load balancer to your application ever again.

In this article, I will use:

  • Visual Studio to build my web application in
  • TeamCity for building and packaging my application as well as for serving as the NuGet server (yes it can do that)
  • Octopus Deploy tool, very powerful .NET deployment tool that synergises well with TeamCity
  • Windows machine that I will deploy the application to

This whole process is easy to do, but it requires a bit of patience and time to set up when doing it for the first time, so follow through, and if you have any doubts or problems you run into when trying to do this yourself, leave me a comment below and I will try to help you.

We well go through several steps to achieve this:

  1. Setting up the basic ASP.NET MVC web application and committing it on GitHub
  2. Connecting the GitHub repository with the TeamCity server and building the application
  3. Enabling the TeamCity NuGet feed functionality
  4. Using the OctoPack to package the application properly and prepare it for the deployment
  5. Setting Octopus Deploy to monitor the TeamCity build and deploy your web application to the target machine

Before going to the deployment process itself, let’s take a more detailed look at the tools we will use.

The required tools

First and foremost, you will need the Microsoft Visual Studio. This is a straightforward choice and I am using the VS2013 for this example, but you can use whatever version you like.

The next thing we will use is TeamCity, the Jetbrains continuous integration tool, the best choice for building your .NET applications because it supports them out of the box. It can also serve as the NuGet server, and thus, makes it easier for us to package and deploy our .NET applications. You can check out my article on Continuous Integration with TeamCity if you want to learn the basics concepts of TeamCity and how to use it to implement the continuous integration practice on your project.

For the deployment part of the cycle, we will use Octopus Deploy, the tool that is developed specifically to automate deployment of the .NET applications. Octopus Deploy offers the free version of the software (Community Edition) which you can use for commercial purposes also. After the trial, you can choose to continue using the Community edition which allows you to deploy five projects and up to 10 target machines, or pick some of the paid plans that offer more flexibility.

Here is how Octopus Deploy fits in the Continuous Delivery cycle.

how Octopus Deploy Fits In

For the target machine, you can use a virtual machine or the physical one, it makes no difference. In this post we will deploy to the windows operating system, so prepare the machine and install the IIS and all the technologies you need for your web application to run. I will not go too deep into the machine setup, but if you are not sure, good starting point would probably be this article on IIS website. It will represent the potential testing or production environment.

So shall we begin?

Setting up the basic ASP.NET MVC web application

The first thing we need to do is to make a basic web application to have something to work with. For the purposes of this demonstration, I will use the Visual Studio MVC template. Go to the File -> New -> Project and select ASP.NET Web Application and name your project.

New web application

I the following dialog, choose the MVC template.

New Project MVC

When the Visual Studio finishes loading the project, you can start it up in the debug mode with IIS express to check if it is working. If it is setup properly, you should see your MVC web application shortly in your browser. You should see something like this.

ASP.NET Application

Now that we have our basic .NET web application set up, we can connect it to the GitHub, so the TeamCity can pull the latest source and build our application. Creating a GitHub repository in not hard and you can find it described in the official documentation. After that, all you need to do is to connect your project with the repo you have created. You can do that by using git bash or some of the fantastic tools available like TortoiseGit.

If you are using git bash you can simply do it like this:

On the other hand, TortoiseGit offers the option to do this using the context menu.

git create repo

That is about it, you have your basic MVC application ready and uploaded to GitHub.

Now we can start with the fun part.

Connecting the GitHub repository with the TeamCity server

I will keep this one short since I already talked about it in detail in my post on how to do Continuous Integration with TeamCity. If you find this explanation too scarce, go check out that article to learn how to import the project in the TeamCity step by step.

The idea is to use the TeamCity’s “Create project from URL” functionality which does some of the work for you and makes this process even easier. Of course, you can go for the manual configuration creation all the way if you want.

So once we have the project set up in the TeamCity and run successfully at least once, we can go to the next step.

Enabling the TeamCity NuGet feed functionality

Enabling TeamCity to act as the NuGet server is pretty straightforward and simple, but the functionality itself is not that easy to spot, or at least, it was not for me. You can find it under the Integrations category in Administration panel.

Nuget feed position

Once there, just click on the enable button and fetch the NuGet version in the NuGet.exe tab and the TeamCity will generate two URLs for you. It should look something like this.

enable nuget packages

As the description states, the first one uses basic authentication, and the other is public and can be used by the guest users. You can enable it by going to the Authentication section in the Server Administration Category.

guest login enable

Now that the NuGet feed is setup, all the NuGet packages created within TeamCity (if you have appropriate privileges) will appear in this feed. So gratz, now you have your own private little NuGet server setup and you can upload NuGet packages to it.

But why did we go through the trouble of setting up the NuGet server, besides it being awesome to have? Because later, when we come to the configuration of the Octopus Deploy tool, it will monitor this feed and get the latest packages for the deployment. How cool is that?

Using the OctoPack to package the application

Another step we must do before the actual deployment is to package our web application. For this, we will use the OctoPack. OctoPack is an open source tool built and maintained by Octopus Deploy company and it makes the packaging of the Windows Services and ASP.NET application easier. It will help us package our application and get it ready for the deployment with Octopus Deploy.

For this to happen we must configure both the project itself and the TeamCity.

You can install the OctoPack through the NuGet package manager. You can do it from the package management console like this:

Or you can use the NuGet package manager:

nuget octopack

When the installation is finished, you can start preparing your application for packaging. First, you need to add the .nuspec file to the project. If you haven’t worked with one before, .nuspec files use the XML format to describe the package. It should be located in the same folder as the .csproj file and have the same name as the .csproj, but with the different extension. So if your project is named YourExample.Web.csproj, you will need to make YourExample.Web.nuspec in the same folder. The typical .nuspec file looks something like this:

Now that you defined the package, we need to tell the compiler to actually run the OctoPack. We can do this by adding the following lines to our .csproj file:

If you configured your project correctly, you should receive the “OctoPack successful” message during the build. You should also be able to find the package within your bin folder.

On thing to note here is that all the files you want to package must be marked as the “Content” and “Copy Always” which is not the case for all the files by default, so be careful and go through the files to check which ones you want to package.

content copy always

That is it for the web application side, but there are some things we must do on the TeamCity side too. OctoPack for the TeamCity comes in the form of a plugin. You can download the OctoPack TeamCity plugin from the Octopus Deploy website downloads page. To enable the OctoPack for TeamCity shut down the TeamCity server and copy the downloaded zip file to the TeamCityDataDirectory/plugins folder. After that, start the server again and if you installed the plugin correctly, you should see a few new options in your configurations.

The first thing you will notice is the addition of the Octopus packaging in your build runner step.

octopus packaging

Check this option and use the build number as the OctoPack package version. Make sure to use the build number that is formed correctly (eg 1.0.3).

Additionally, we have three new options in the build runner dropdown now.

octopack options

Octopus Deploy: Create release creates the release and optionally deploys it to the target environment, Deploy release, deploys the existing release to the target environment and Promote release promotes an existing release from one environment to another.

For our example, we will use the Create release build step, but since the configuration of this step largely depends on having the Octopus Deploy server installed and configured, let’s leave it for now and come back to it once we have installed the Octopus Deploy server.

Setting up Octopus Deploy

Finally, we come to the step where all pieces of the puzzle come together. Octopus Deploy consists of two major parts. First is the Octopus Deploy server, and the other is the light client called Tentacle. Octopus server is the brain of the system and it is used to configure and orchestrate all the “tentacles” and target environments. Tentacle is installed on every target machine and it communicates with the Octopus server through secure gateways. Both the Octopus server and the Tentacle can be downloaded from the Octopus Deploy downloads page.

Let’s begin with the Octopus server installation. When you start the msi package, you will go through the installation wizard, and when you are finished, you will be looking at the octopus manager UI. Through it, you can access the Octopus Web Portal in the browser, using the credentials you created during the installation.

The first thing you should do in the web portal is creating an environment. In the Octopus Deploy, environments represent a group of machines you will deploy your applications to at the same time. Environments could be, for example, Staging, Testing, Production and so on. Later on, you will be able to add a number of machines to those environments.

For now, let’s add one environment called Staging. After that, you can add the Target machine to it. Install the Tentacle in the listening mode on the target machine and check its IP address and port. You will use this information while adding the target machine in Octopus server.

New Deployment Target - Octopus Deploy

After that, you should have something similar to this in your Environments.

Environments - Octopus Deploy

Ok, now that we have prepared the target machine and environment, we can go back to the TeamCity and add the deployment step. Go to the project build configuration and add the Octopus Deploy: create release step.

Octopus Deploy create release - TeamCity

Octopus URL is the URL of the Octopus server, and you can find the API key through the Profile -> API keys in the Octopus server. Simply paste the key here, name the project and put the created environment name in the Deploy to property and that is it.

Now we can configure the deployment process in the Octopus server. To do this, we will add the new project and name it. After that select the project you created and go to the process tab. In there you can add steps to the deployment process. Click on the Add Step button and choose Deploy a NuGet package option. Configuring the deployment process might take you a while and requires a bit of experimentation but once it is set up properly, there is no need to tweak it often.

Since we are deploying a web application, we should be able to configure IIS in this process. You can add the IIS configuration options to the process by sliding a bit down and clicking on the Configure features option. Then, select the IIS web site and application pool option from the list.

Enabled features - Octopus Deploy

After that, you can configure the IIS application pools, bindings and authentication within the Octopus Deploy.

Let’s quickly go through the configurations options:

Package:

From the NuGet feed dropdown select the TeamCity feed option, and then add the NuGet package id below (it was defined in nuspec file). Select the preferred option for the package download.

Configuration variable:

Leave it as is.

Configuration transforms:

You can leave it up to Octopus Deploy to do the transforms for you or you can add your own if you need.

IIS Web Site

Select the Create or update website option and name the website. You can use a number of predefined Octopus Deploy variables for this. I use something like ProjectName-#{Octopus.Machine.Name}. Add the root path if you need to.

IIS Application Pool

You can create the App pool for the website here.  Again, for the name, you can use something like ProjectName-#{Octopus.Machine.Name}. Choose the version of the CLR and select Network Service for the Identity.

IIS Bindings

Add your own preferred bindings here.

IIS Authentication

For this example, I use the Anonymous authentication, but you can choose whatever you want.

Conditions

Leave it as is.

That is it. Your application is all wired up, and ready to be deployed. If you are running your website locally, don’t forget to add the binding to the hosts file. Run the build and wait for the result. You may not be able to deploy it instantly, but read the feedback messages in the TeamCity and Octopus Deploy and you will have your automated deployment process set up in no time.

For the detailed instructions on how to set up Octopus Deploy, you can go to the Octopus Deploy documentation page or watch the Octopus Deploy training videos on youtube.

Conclusion

As you can see, setting up the automatic deployment process with the TeamCity and Octopus Deploy includes quite a bit of steps and some effort for the configuration.

But it is worth it!

You didn’t have to use the FTP or Web Deploy or run custom PowerShell scripts. And the whole process is scalable and flexible. It is easy to add new machines or environments and to change existing. You can also monitor the health of the machines in the network and oversee everything from one place.

Hope this article helped you improve your deployment practices and made your life, at least, a bit easier. Please share your experiences in the comments section below.