Running a Visual Studio Build vNext agent in a Docker container

Update: 27-10-2016

Take a look at the official Microsoft Docker Images on DockerHub that also contain a Build agent


With the introduction of the new build engine in Visual Studio Online and Team Foundation Server 2015, Microsoft also introduced real cross-platform build capabilities,

The VSO-BuildAgent and tasks are both published as Open source on Github and allow you use and extend.any way you like.

With the ability to run cross-platform builds, I wanted to try out the build agent on Linux. The page on Github describes how to configure your linux machine, but this post from Kees Verhaar describes it much more detail.

This is great! But I wanted more. In my previous post I talked about Docker and how I like the idea of having isolated containers that run independently. Running a build agent is a perfect example where you want isolation. Surely you can run multiple agents on 1 machine, but you also need tools which will do the actual work. For that, you need to install compilers, tools etc.

Not every agent has the same requirements but they do have the same requirements when you share the same machine.

So I decided to try and create a Docker container with build agent. This container can then server as a base container and I can create separate containers for each need.

First I needed to set-up my Linux and Docker environment. I described that adventure in my post, [Get started with Docker on Azure for Microsoft Developers and Linux noobs]. After that the building of the Docker container was my next challenge.

Way of work

To create a Docker container from scratch, you need to write a DockerFile. Because I did not really know what I needed I decided to approach it differently. I created a blank Docker container and tried to make the Build Agent work there. I created a connection to my Linux machine in Azure and created a Docker container from the Ubuntu 14.04 image.

First I pulled it from Docker Hub

$ docker pull ubuntu:14.04

and then I run an instance with an interactive prompt so I can type commands within the container.

$ docker run -t -i ubuntu:14.04

If everything is well, you are in a command prompt like this root@b408c7134d8e:/#

Then I followed the steps described on the blog of Kees and Github. Run these commands (not the # prefixed) one by one.

# Make sure you have the latest updates
sudo apt-get update# INSTALL NODE.JS
sudo apt-get install expect -y
sudo apt-get install nodejs npm -y
sudo apt-get install nodejs-legacy -y#install the VSO Agent
sudo npm install vsoagent-installer -g#create some dirs where you can store your build agent
mkdir opt/buildagent
mkdir opt/buildagent/_work

Now that you have the vso agent installed, you need to run it. You cannot run as “root” user so you need to add a “service account” for this.

# add a service account user for vso build agent
adduser vsoservice

Answers the prompts by providing a password and (optionally, just press enter to skip) other user details

Then go to your created directory and run the vsoagent-installer. This extracts (installs) the vso agent in the current directory.

#run installer
cd opt/buildagent
vsoagent-installer

 

Because the agent runs under vsoservice, we need to assign rights to vsoservice (chown –> change owner)

#assign rights to vsoservice to write files int the build agent directory
sudo chown -R ${vso_service_username} /opt/buildagent

 

Then run the agent. You cannot run as root so you need to switch to the vsoservice user (su vsooservice). With the node agent/buildagent command you install the agent. Because this is the first time it asks you for credentials (use the alternate credentials) and url etc.

#switch user because we cannot run as root
su vsoservice

#start up agent
node agent/vsoagent
# alternate username
# alternate password
# server url (https://name.visualstudio.com)
# agent name
# pool name

The configuration is saved in a hidden directory called .agent . If you want to reconfigure your agent, simply remove this .agent directory. You can find hidden directories by typing ls -a

cd opt/buildagent
ls -a
rm .agent

Et Voila ! We have our build agent running in a Docker container!!

Make it reusable

Now that we know all steps to configure our agent in a Docker container we need to make this more generic by creating a Dockerfile. On my host Linux I created a directory [docker] and created a new File  called Dockerfile. I downloaded Visual Studio Code for editing files on the linux machine.

image

The Dockerfile basically contains all statements that we executed before, prefixed within some Docker specific commands.

image

In the screendump above you see a part of the DockerFile. Let me explain a bit.

  • Line 1: FROM ubuntu:14.04 is pointing to the base image you will use.
  • Line 2: MAINTAINER says something about who maintains the image
  • Line 4: RUN runs the command on the command line.

When I Dockerfied (is that a word?) all the commands in a Dockerfile, it was time to build an image from that file. You can create a Docker image by running (note the dot (.) at the end of the line. This means find a dockerfile in the current directory) the following command inside the docker directory

docker build -t rvo/vsobuild:v1 .

 

After this you have an image containing the installed agent.  You can startup the docker container by running the commands

#find all images on your system
docker images#run image that you just created
docker run -t -i rvo/vsobuild:v1

 

But now you have to login to the image and configure the agent. I want to have a self containing image that I can run, which automatically starts a build agent. To configure the agent on the command line we need to navigate to our [opt/buildagent] directory and run the command [node agent/vsoagent] (just as explained above) and answer some questions about the installation. I wanted to automate those steps and answer the questions interactively.

On Linux there is a command line tool called Expect which enables you to build a file that answers interactive questions for you. You need to have Expect installed on your system and you can do that running the command

sudo apt-get install expect -y

 

Then you need to create a file which contains the expect commands

#!/usr/bin/expect
spawn node agent/vsoagent
expect “Enter alternate username” { send “$env(vso_username)\n” }
expect “Enter alternate password” { send “$env(vso_password)\n” }
expect “Enter server url” { send “$env(vso_url)\n” }
expect “Enter agent name” { send “$env(vso_agentname)\n” }
expect “Enter agent pool name” { send “$env(vso_agentpool)\n” }interact

 

Note the $env(variable) placeholders. These are references to environment variables which we will send from the command line (later this post). Save this file in the same directory as your Dockerfile and call it ConfigureAgent.expect.

We can run this file by typing the following command within our Docker image.

expect ConfigureAgent.expect

 

We need to copy this file into our Docker container so that it is present when running it. For that we need to run the copy command in our Dockerfile

image

Then we need to run this file every time a Docker container is started. For that we need a shell script. So we create a new file in the same directory called run.sh. This file contains the run command of the expect file. Because we need to run as vsoservice instead of root the syntax is slightly different.

#!/bin/bash
su $vso_service_username -c ‘expect ConfigureAgent.expect’

 

Save this script into a file called run.sh and add this file also to the Docker image by adding another COPY command and give it rights to execute.

image

The we only need to add a command to our Dockerfile that runs this script We can Fix this by adding the CMD command to our Dockerfile

image

Now we have a Dockerimage that runs a build agent. The only thing that we need to do now is fill the environment variables that are used in the expect file. We can use the ENV command in the Dockerfile to add those variables

image

Those variables are present in the image once it is started and can be used everywhere. Now we need to build a new Docker image from this new Dockerfile and run this image by providing the environment variable values.

#Build the new docker image
docker build -t rvo/vsobuild:v2 .#run the image
docker run -t -i -e vso_username=<vsousername> -e vso_password=<vsopassword> -e vso_url=https://name.visualstudio.com -e vso_agentname=MyFirstAgent rvo/vso:v2

 

When you ran these command you hopefully get this result

image

For your convenience I have the full Dockerfile, run.sh, ConfigureAgent.expect and example RunCommand.txt as a download here on github

Happy building !

.

15 Responses to “Running a Visual Studio Build vNext agent in a Docker container”

  1. I just discovered this brilliant article after I watched connect;//2015…Thank you for sharing this…

  2. Paramesh Palanisamy November 3, 2016 at 3:04 pm

    Hi. I want to pull the code from TFS to my docker container. How can i do that

  3. I wonder if dockerized build agent can be used to build VS 2015 solution. May I do that?
    What I would like is to run new docker container, this docker container clones a certain branch from a git repo and builds it.

Trackbacks/Pingbacks

  1. Get started with Docker on Azure for Microsoft developers and/or Linux noobs | The Road to ALM - August 7, 2015

    […] In my next post I will talk about how to create a Docker container which runs a Visual Studio Build vNext agent […]

  2. Running a Visual Studio Build vNext agent in a Docker container | Dinesh Ram Kali. - August 15, 2015

    […] https://roadtoalm.com/2015/08/07/running-a-visual-studio-build-vnext-agent-in-a-docker-container/ […]

  3. Visual Studio – Developer Top Ten for August 17th, 2015 - Dmitry Lyalin - August 18, 2015

    […] Running a Visual Studio Build vNext agent in a Docker container by Rene van Osnabrugge […]

  4. And now, the Friday Fives! - The Microsoft MVP Award Program Blog - Site Home - MSDN Blogs - October 16, 2015

    […] Visual Studio and Development Technologies MVP Rene Van Osnabrugge @renevo: Running a Visual Studio Build vNext agent in a Docker container […]

  5. Unattended install of a Visual Studio Team Services (a.k.a. VSO) Build Agent | The Road to ALM - November 26, 2015

    […] and on startup I wanted to run a configured agent. I solved ths by using an expect file on Linux. Take a look at my post how I did […]

  6. Create a Windows Docker Host and connect to it without Visual Studio | The Road to ALM - December 30, 2015

    […] Running Visual Studio Build Agent in a Linux Docker Container […]

  7. Running a VS Team Services (VSO) Build Agent in a Windows Docker Container | The Road to ALM - February 15, 2016

    […] Running a Visual Studio Build vNext agent in a Docker container […]