2015 Ignite New Zealand demo prep: Step 8


  1. Intro
  2. VSO
  3. Docker
  4. xUnit
  5. Build
  6. Back end
  7. Selenium
  8. Docker
  9. Release Management
  10. Testing

In this post, we are going to build the Docker image and store it in DockerHub.  The goal is to only produce the image once and simply deploy it to multiple hosts as we promote the image from one environment to the next.

We are going to use the new ASP.NET 5 configuration feature to allow us to change configuration information as we run the image.  This will enable changing connection strings and other information using the same image we produce and store in DockerHub. We are going to tag each image with the build number generated from VSTS. The tag will let us identify the correct version of the image to run on each host. Using tags allows multiple images to be in flight at the same time.

If you do not have an account on DockerHub, create one now and create a repository.  We will use the repository you create to store the images we create.

To build the image, we must first publish our ASP.NET 5 application. We are going to do that using a simple batch file.  The batch file will take two arguments. The first will be where to find the project.json file for the ASP.NET project. The second argument will be where we want to store the published files from which we will build our Docker image.

  1. Create package site batch file
    1. Open PeopleTracker.sln
    2. Right-click on PublishProfile and select Add / New Item…

    3. Select Text File
    4. Name the file packagesite.cmd
    5. Copy and paste the code below into the file

      set path=%USERPROFILE%\.dnx\runtimes\dnx-clr-win-x86.1.0.0-beta8\bin;%ProgramFiles(x86)%\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Web Tools\External;%1\node_modules\.bin;%path%

      dnu.cmd publish "%1" --out "%2" --wwwroot-out "wwwroot"

      exit /b 0

    6. Update dnx-clr-win-x86.1.0.0-beta8 to your current runtime
      1. You can find this from the build output for the first PowerShell we run in our build
    7. Commit and Push your changes
  1. Update build to call batch file
    1. Edit your build
    2. Click Add build step…
    3. Select the Utility section
    4. Add a Batch Script task and close the Add Tasks dialog
    5. Drag and drop the task above the Copy and Publish Build Artifacts task
    6. Use the browse button and select the packagesite.cmd file we just added
    7. Copy and paste the code below into the Arguments text box
      $(Build.SourcesDirectory)\PeopleTracker\src\PeopleTracker.Preview $(Build.SourcesDirectory)\DockerStage
    8. Check the Modify Environment check box
    9. Save and Queue your build
    10. Confirm it builds as expected

Now that our build is able to produce the packaged version of our ASP.NET 5 application, we need to build an image and publish it to DockerHub.  When we originally published to our Docker Hosts from Visual Studio, several PowerShell scripts were created. We are going to use and modify some of them for use in our build.

  1. Modify PowerShell to publish to DockerHub
    1. Open the publish.ps1 file for your dev environment in the PublishProfiles folder
    2. Add the following code above the if(!$buildOnly) { line

      Write-Verbose 'Time to push to Docker Hub'
      $command = 'docker{0} -H {1} push {2}' -f $authOptions, $dockerServerUrl, $imageName
      $command | Print-CommandString
      $command | Execute-CommandString | Write-Verbose
      'The Docker image "{0}" was pushed successfully.' -f $imageName | Write-Output

    3. Repeat this for the QA and Prod versions as well

For the agent to be able to execute those new lines, you have to log in to DockerHub from your agent machine. Once you do, your credentials will be saved on the agent.

  1. Log in to DockerHub from agent
    1. Open a command prompt on your agent machine
    2. Execute the following command

      docker -H tcp://{DockerHost}:2376 --tls login -e [DockerHubEmail] -p [DockerHubPassword] -u [DockerHubUsername]

The PowerShell script takes three arguments.  The first is a hash table you can use to override values supplied in the pubxml created for us by the Docker Tools for Visual Studio when we created our Docker Hosts. The second is the directory we want to place our image into. The final argument is to the pubxml file.

We are going to use the first argument to instruct the PowerShell to simply build the image and not start it.  We are also going to override the image name by appending the build number as a tag. This will allow us to identify which build created each image in DockerHub.

  1. Update build to call PowerShell
    1. Edit your build
    2. Click Add build step…
    3. Select the Utility section
    4. Add a PowerShell task and close the Add Tasks dialog
    5. Drag and drop the task above the Copy and Publish Build Artifacts task
    6. Use the browse button and select the devdockerhost-publish.ps1file we just modified
    7. Set the Arguments to

      -publishProperties @{"DockerRemoveConflictingContainers" = "false"; "DockerBuildOnly" = "true"; "DockerImageName" = "{YourDockerHubUserName}/{YourDockerHubRepo}:$(Build.BuildId)"} -packOutput $(Build.SourcesDirectory)\DockerStage -pubxmlfile ".\devdockerhost.pubxml"

    8. Under the Advanced section set the Working Folder to the PublishProfiles folder
    9. Save and Queue your build
    10. Confirm it builds as expected

After you build succeeds, you can return to DockerHub and see your new image.

With our build complete, we will move into Release Management in the next post.

Comments (5) -

  • David Stiff

    12/22/2015 9:24:05 PM | Reply

    Hi Donovan,
    when can we expect RM2015Update1 (on-prem version with the new web interface)?

    • Donovan

      12/24/2015 1:04:59 AM | Reply

      We are targeting Update 2 for RM on prem.

  • Aaron Taylor

    1/7/2016 1:54:18 AM | Reply

    Hi Donovan,

    I am having issues with Step 4 above...."Log in to DockerHub from agent". Should I be replacing '{DockerHost}' with my dev docker host url? When I attempt to do that I get a 403 'Request forbidden by administrative rules' error.

    Also, my builds were completing successfully up to this stage but all of a sudden my builds are failing at the Install_DNX.ps1 stage with the error 'Get-ChildItem :
    The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters. At C:\Agent1\_work\1\s\Install_DNX.ps1:24 char:1'

    Have you experienced this issue?

    Many Thanks,

  • Richard Angus

    2/13/2016 7:48:30 AM | Reply

    Update: The issue that Aaron is having with path lengths is due to one of the scripts that restores the DNX stuff is also restoring the Node stuff. This gives a set of very deeply nested paths that PowerShell has trouble dealing with .The trick is to ensure that in your build definition that you tick the Clean option on the first tab. This forces the build agent to clean the working directory first, and the PowerShell scrip then is able to read all the directories to find the project.json files.
    Hope that helps someone - was bashing my head against the screen for a few hours on that one

Pingbacks and trackbacks (15)+

Add comment