VSTS: Build and Deploy on your own Server
Visual Studio Team Services provides an excellent cloud-based solution for project management and code repositories (both TFS and Git). Part of our standard process at Trailhead is to set up Continuous Integration builds and deployments so the team and client can get immediate feedback on unit tests and visibility into the current state of the application.
VSTS has a straightforward process for setting up CI in a hosted Azure environment, but I’ll walk you through the steps to set up a CI process using your own server, whether it is a server sitting in your office or a VM hosted with another cloud provider.
Why should I use my own server?
Running builds and deployments on your own server isn’t for everyone, but here are a few reasons why you might consider it:
- It may be cheaper to run a VM with a provider other than Azure.
- A VSTS project has a limited amount of free build minutes. You have unlimited build time on your own server.
- Depending on the server you use, build times may be much faster.
- You already have a VM running elsewhere and it makes sense to reuse it.
- Your project may require hosting configurations that are not available in a hosted Azure instance.
Project and Server Setup
Before we get started in VSTS, make sure you have:
- Your VSTS team and project set up. If you don’t have one, create one for free at visualstudio.com
- Basic configuration of your server/VM ready. For typical builds, you’ll need at least MSBuild and/or Visual Studio (Community Edition works) installed.
Set up your Agent
Now let’s set up our Agent Pool and Agent. An Agent is the process/machine that will be doing the work of building and deploying your project. It can be the Hosted agent that is included with VSTS, or a “private agent” which you host yourself. At the time of writing, you get one free private agent with your account. Additional agents can be purchased for $15/month.
In your VSTS project, go to Settings, Agent Pool, click “New pool…” and give it a name.
Next, click the “Download agent” button which will open a window with detailed instructions and a download link for files that you will deploy on your server.
The basics of the agent setup are:
- Unzip the setup zip file in a directory on your server
- Run config.cmd which will require your VSTS info and an access token (details for Windows here)
- Install the agent as a service (recommended for long-term use) or run it interactively with run.cmd (a good option to quickly get running and try things out)
NOTE: When you install the agent as a service, either create a new user account to run the service under or use an existing account like NETWORK SERVICE. You will need to grant this user permissions to your deployment directory so it can properly deploy files.
When you run the agent, it will scan the server for capabilities and then connect to VSTS where it will show as Online. You can also view the “Capabilities” tab to see the results of the scan that was run when the agent was started.
Configure Build with Agent
Now that our agent is set up, we can configure a Build that will run on the Agent. With our private agent configured, we can use the default Visual Studio template for most of what we need.
Go to Build & Release > Builds > New and select the “Visual Studio” template. In the “Create new build definition” window, select your repository, branch, check the Continuous Integration box (if you want this build to run as CI) and select your agent in the agent queue drop down:
After the build definition has been created, you can inspect the settings. Typically, you can use all of the default settings.
However, be sure to add the following commands under the Visual Studio Build step in the “MSBuild Arguments”:
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation=$(build.stagingdirectory)
This will create MSDeploy packages in the build and drop folders that we will use later for deployment.
Configure Release with Agent
The final step is to set up automated releases within VSTS. This will give us a deployed version of our app with every push to the repository.
NOTE: Before you configure a release, set up your application in IIS on your server and give Read/Write permissions on that folder to the user that is running the build agent (NETWORK SERVICE is used in our setup).
Go to Build & Release > Releases > “+” to create a new release definition. Select the “Empty” template.
For a typical CI release, select Build artifacts, your project, set the Source to your previously defined Build Definition, select Continuous Deployment, and set the Agent Queue to your private agent (so the release will run on your server).
After you click “Create,” you should see an Environment created and an empty Task panel. Click on the “Run on agent” link to confirm that your private agent is selected in the Deployment queue dropdown.
We will only need to add a single batch script task: click “Add tasks” > Utility > Batch Script.
There will be two parameters for the script that you need to set. First, the Path. Use the ellipses button (…) to browse the current build directory (trigger a manual build if you don’t see anything here–it helps to see the built files and folders in this step) and select the “*.deploy.cmd” file for the project you want to deploy. It will look something like this:
Next, set the IIS site name in the Arguments box and fill in the “value” part of the parameter with your IIS Site name to deploy to:
"-setParam:name='IIS Web Application Name',value=MyIISSiteName" /Y
This tells Web Deploy which IIS site to use for deployment.
The full Release definition will look something like this:
Switch to the Triggers tab and confirm that it is configured for continuous deployment.
You now have a platform to use for as many projects as you’d like! The agent can be reused and you can set up multiple build and release definitions to use your private server agent. If you find yourself running lots of CI builds and there is often a wait in the queue, you can set up multiple Agent servers and deploy to all or some of those servers.