In this article, we will create a .NET Core application and its Docker image using Jenkins. All the technologies are compatible with Windows, Linux and Mac OS. Let’s start with a few words on each of them.
.NET Core
According to the Microsoft website:
.NET Core is a lean and composable framework for building web and cloud applications
Put simply, .NET Core is a cross-platform and open-source implementation of the .NET Framework. It contains the core features of the .NET Framework, including runtime environment, compiler, libraries and additional tools components that support a variety of operating systems.
Jenkins
Jenkins is an open source Continuous Integration application for building, testing and reporting on changes in a larger code base in real time. The software enables developers to find and solve defects rapidly and to automate testing of their builds. It supports version control systems like Git, Subversion and many more.
Docker
Docker is an open-source set of tools that provides the so-called “containers” – applications run securely in an isolated environment. A container wraps an application with all its dependencies: binaries and configuration files, system tools, libraries – anything that has to be installed on a destination server. It also includes parts of an operating system required to run a container.
To compare classic virtual machine and Docker images, let’s have a look at the picture below:
Docker containers are similar to virtual machines but without the overhead. A standard virtual machine needs binaries and libraries, and an entire guest operating system with its own memory management for each application. All of it can amount to lots of GBs and requires time to load. Containers that runs on top of Docker Engine share the kernel with other containers but are isolated processes on the host operating system. Docker containers are therefore smaller, lighter and faster. They are also more scalable as compared to VM’s.
Integration
The goal is to create an automated process of deploying the new version of the application to Docker images repository, starting from committing changes to version control system repository (in this case, Github). For the purpose of this project, we will also use Docker Hub, a cloud-based repository of Docker images. Shortly, Jenkins should check the Github repository every hour looking for commits. When it finds any, it will compile sources, create an image and send it to Docker Hub.
Our target platform is Ubuntu 14.04, but Windows or Mac OS could be used as well. Before starting, .NET Core, Jenkins and Docker should be installed as well. You can find useful links in a section at the end of this page.
Let’s start from the beginning and create a default ASP.NET Core MVC solution in Visual Studio 2015 – it proceeds in the same way as in previous versions of MVC.
The structure of the project is similar, but a significant difference is the main configuration file – project.json (not web.config as before). There are a few sections, but let’s have a look at the section “frameworks”:
"frameworks": {
"netcoreapp1.0": {
...
}
}
Target framework for ASP.NET Core MVC projects is .NET Core 1.0 in default. More information about TFM (Target Framework Monikers) you can find in this article on MSDN blog.
ASP.NET Core MVC solution can be easily integrated with Docker, the only requirement is to install the extension for Docker to Visual Studio 2015 and add Docker Support, as it is shown on the picture below.
Docker images are built by instructions from Dockerfile, a configuration file that contains commands needed to assemble an image. Example Dockerfile looks like this:
FROM microsoft/dotnet:latest
COPY . /app
WORKDIR /app
EXPOSE 5000/tcp
ENTRYPOINT ["dotnet", "run"]
Here is what each of these instructions does:
- FROM tells Docker that we want to base our image on the existing image (microsoft/dotnet:latest), that already contains all the dependencies for running .NET Core on Linux
- COPY and WORKDIR copy the current directory’s contents into a new directory inside the container called app, and set that to the working directory for the subsequent instructions
- EXPOSE informs Docker that the container listens on the specified network port – 5000 (the default port for ASP.NET)
- ENTRYPOINT specifies the command to execute when the container starts up. In this case, it is dotnet run
Full documentation for configuring Dockerfile can be found under this link.
The next step is to configure Jenkins, which requires installing Github and Docker plugins (check the Plugin Manager section). We will poll Github repository for new commits and, if there are any, build a Docker image and push it to Docker Hub repository.
Using Docker Hub requires creating an account under this link (it is free).
Let’s create a new job in and set the URL to our version control system repository:
Then, schedule our job to poll the Github repository, e.g. once per hour:
The last step is to add execute a shell script to build steps. Here is the example script:
dotnet restore
dotnet publish -c release
docker build -t dockerhubuser/simplecoreapp:v0.${BUILD_NUMBER} .
docker login -u dockerhubuser -p dockerhubpassword -e [email protected]
docker push dockerhubuser/simplecoreapp:v0.${BUILD_NUMBER}
And, what each of these instructions does:
- dotnet restore – restores dependencies specified in the project.json file from NuGet
- dotnet publish – builds and packs the application and all of its dependencies into a folder, getting it ready for publishing
- docker build – builds an image from a Dockerfile. Jenkins replaces variable ${BUILD_NUMBER} to number of actual build
- docker login – logs into a Docker Hub using account credentials
- docker push – pushes an image to Docker Hub
The job will be automatically fired after committing any changes to Github repository. Presented process can be developed, e.g. to use Unit Tests or any other functionalities.
Summary
What we have accomplished is a fully automated process of deployment Docker image of the application to images repository. It can be managed and used by external tools to provide container-centric infrastructure in a cloud computing platform.
This article is the first of two on this blog, describing the process of building CI pipeline using such technologies as .NET Core, Jenkins, Docker, Kubernetes and Spinnaker. More information in the second article describing Continuous Integration pipeline, soon on this blog. Stay tuned!
Useful links
- Download Ubuntu
- Install .NET Core on Ubuntu
- Install Jenkins on Ubuntu
- Install Docker on Ubuntu
- Visual Studio Tools for Docker – extension