Why it's the right time for .Net developers to embrace Jenkins and Docker
The Agile movement in software has created a market for various different tools, each automating a specific part of the development process. For instance, the call to continuous integration (CI) has given rise to the likes of Hudson/Jenkins and Maven that allow you to concentrate on the task at hand while getting precious feedback within seconds.
The .Net platform and the ecosystem surrounding it have been latecomers in providing decent tools for CI. Team Foundation Server (TFS) took a long time to provide anything more than a glorified copy of Apache Ant. The introduction of NuGet has helped somewhat with dependency management. Jenkins has had a plugin for MSBuild since 2008, providing an alternative to TFS. However, most IT departments who are fully enslaved by invested in Microsoft's products are loath to take what they consider to be a huge risk.
However, in a somewhat surprising turnaround, Microsoft has recently declared its love for Linux and open source software. This sentiment has been followed by the release of the first fully Microsoft supported implementation of the .Net framework for Linux which enables building and running ASP.Net applications from a Linux command line. This should help companies to take a chance on using more and more open source tools, especially ones that are currently only available on Linux, like Docker for instance. Microsoft has even announced a partnership with Docker and are working on fully integrating it with Windows.
- Why it's the right time for .Net developers to embrace Jenkins and Docker
- What's in this lab
- Install VirtualBox
- Install Docker & Docker Machine
- Install Docker Compose
- Set up a virtual machine with Docker
- Transfer SSL client keys to the virtual machine
- Create Docker containers for GitLab and Jenkins
- Configure GitLab and create a project
- Configure Jenkins and create a build
- Run the resulting Docker image
- Where to go from here
What's in this lab
This lab will show you how to set up a virtual machine with a Git repository, and an instance of Jenkins, each inside their own Docker containers. A very simple ASP.Net application without any tests will be pushed to the repository. Then using a Jenkins Pipeline-as-code build, we'll produce a Docker container. Finally we'll run that container and check that our application is in fact running.
Tools and versions used in this lab
|GitLab||Community Edition 8.7.0|
This lab assumes that you are already familiar with these tools.
Make sure that your machine has 64bit CPU that supports virtualization. You may have to activate virtualization support via your machine's BIOS setup utility.
If you're on Linux, you also need Git installed.
Download and install Oracle VM VirtualBox using the appropriate installer for your OS.
Install Docker & Docker Machine
On Windows or Mac OS X, install Docker Toolbox. This will install both Docker and Docker Machine, along with Git.
On Linux, follow Docker's instructions for installing Docker then Docker Machine.
Install Docker Compose
Again, follow Docker's instructions for installing Docker Compose.
Set up a virtual machine with Docker
Thanks to Docker Machine this is a very easy step. In your favorite terminal — on Windows I recommend PowerShell over CMD — type the following command to create a virtual machine named "default" that runs Linux and has Docker installed.
After it has been created, the machine boots up in headless mode. On the first run, Docker Machine generates keys for securing SSH connections to the machine as well as TCP connections to the Docker daemon running on it.
Docker Machine provides several commands for stopping and starting the machine, as well as connecting to it via SSH, and setting the appropriate environment variables for connecting to its Docker daemon.
Speaking of which, use the following command to find out how to do that on your terminal and do it.
On PowerShell under Windows, this would output something like this:
We can see that Docker Machine set up the Docker daemon on the virtual machine to listen to TCP connections on port 2376. However, not everybody has access; only those that use the right SSL certificates. Thankfully Docker Machine also placed those certificates in
.docker/machine/machines/default in your home directory.
Once you execute the suggested command, any subsequent invocations of Docker will talk to the virtual machine's Docker daemon.
Transfer SSL client keys to the virtual machine
In order for Jenkins to build and run Docker containers, it needs to be able to communicate with a running Docker daemon. One way to do this would be to install one inside the container alongside Jenkins: this has been dubbed "Docker in Docker" or DinD for short. This does not work, as someone else explains. Another way is to allow the Jenkins container to see the daemon that's running it: similarly this is called DooD. There are many blog posts out there that explain more or less convoluted ways of doing that.
In this lab, we'll have Jenkins connect to that same TCP port that the Docker daemon is already listening to. Since this port is encrypted, we need to provide certificates for making client connections. One easy way is to reuse the ones that Docker Machine has already created.
Use Docker Machine to copy those certificates to the virtual machine for later use.
To check that this has worked, you can connect to the virtual machine and list the contents of
Create Docker containers for GitLab and Jenkins
Create a new directory called
aspnetci and a new file within it called
docker-compose.yml with the following contents.
Once this is done, run the following command from the
Configure GitLab and create a project
An instance of GitLab is now available at http://192.168.99.100:8000. It will require some initial configuring so go to that address.
Firstly, it will prompt for a new password for the
root user. Provide one (and remember it ).
Secondly, log in as
root, and create a new empty project. Let's call it
Thirdly, create a new directory on your machine and open a terminal in that directory. Use the following commands to clone a simple ASP.Net application and commit it to GitLab.
Configure Jenkins and create a build
An instance of Jenkins is available at http://192.168.99.100:8001. It also requires some configuration.
Firstly, it will prompt for the initial password. This is generated randomly and stored in a file inside the Jenkins container. It can be retrieved using the following command.
Then, let Jenkins install suggested plugins. Once that is done, you will be prompted to create a new user.
Install the Docker Commons Plugin and add an installation for Docker entering the following information:
- Name: Default
- Install Automatically: check
- Add installer: Extract *.zip/*.tar.gz
- Download URL for binary archive:
- Subdirectory of extracted archive: docker
Finally, create a multibranch pipeline entering the following information :
- Branch sources > Add source: Git
- Project repository:
- Credentials: root/******
Once you have saved this the build should trigger. It will scan the Git repository to find all branches that have a pipeline build script named
Jenkinsfile, then use that script to build the branch.
This script carries out the following steps:
- check out the current branch from the Git repository
- ask Jenkins for the directory where it installed a Docker client
- add that directory to the
- run the following steps in a Docker image that has the ASP.Net runtime and development tools installed:
- fetch dependencies from NuGet repository
- package the project as a publishable artifact
- assign ownership of all files created during the previous steps to the
jenkinsuser (otherwise Jenkins won't be able to complete the next steps)
- build a Docker image using the Dockerfile contained in the project, tagging it using a combination of the branch name and the build number
Once the build is finished, you can check that the Docker daemon knows of the image by using the following command.
Run the resulting Docker image
Run the Docker image with the following command.
The application should be available at http://192.168.99.100:5004.
Where to go from here
So now you have a simple ASP.Net application that can be built with a multibranch pipeline Jenkins build. If you create a new branch and add a feature, you can build and test drive it in a new container.
There's still some way to go before we have a production-ready application and build. Here are just a few things that could be added:
- Unit tests: https://xunit.github.io/docs/getting-started-dnx.html
- A data layer:
- with data stored in a database in another container
- using Entity Framework 6 for persistence: https://www.asp.net/mvc/overview/getting-started/...
- Integration tests that run against an ephemeral container: https://www.digitalocean.com/community/tutorials/...
- Publishing of the Docker image to a Docker (Trusted) Registry
- Continuous Delivery:
- add a parameterized build for deployments, or
- add steps to the existing build pipeline