A few months ago I have started working on a new, greenfield, project. Since it’s a one-man job, it was crucial for me to have an easy setup without big dev-ops needs - especially in the early beta stage. I decided to use Docker because I could automate the building process using pipelines in GitLab and Docker Cloud for deployment. Today I would like to show you how to setup Continous Integration for an ASP.NET Core project using GitLab pipelines.
- Creating new app
- GitLab Pipelines
- Adding tests project
Creating new app
To create a new application, you can use
dotnet new web command. It creates an empty web application, which does one thing - displays famous
Hello World. To start it you need to first restore all the dependencies with
dotnet restore and then issue
You now have an application. Let’s containerize it. To build a Docker image, you need to create a
Dockerfile. It’s a set of instructions for Docker so it knows how to create an image. You can read more about Docker files in the official docs. There’s also a very nice post by Jakub Skałecki with tips on how to write better docker files.
Official Docker images for ASP.NET Core are available on the Docker Hub and there are few options to choose from:
- microsoft/dotnet - this is a base .NET Core image. You can use it to build and run all types of .NET Core applications.
- microsoft/aspnetcore - this image is optimized for running ASP.NET Core applications. It contains .NET Core and a set of native images for all of the ASP.NET Core libraries, so that these libraries don’t have to be compiled by JIT, which gives you faster cold start of your application.
- microsoft/aspnetcore-build - it also contains all of the ASP.NET Core stuff, but also an SDK, which allows you to build apps in the container. It also has Node.js, Gulp and Bower.
Because we are going to use GitLab Pipelines, which don’t have dotnet SDK preinstalled, you will build the application in the container. Therefore you need the
Microsoft/aspnetcore-build image. When the application is built you will use simple
Microsoft/aspnetcore image for running the application.
Format and purpose of this file are identical to
.gitignore. It’s a way to tell Docker, which files or directories you don’t want it to copy to your container. In our case, it’s just two folders for now. In a real app, you might want to add things like
This is the most important file in the docker world. It tells the Docker engine how to build your image.
As you can see, there are two stages. In the stage one we’re using the build image and then, when it’s done we copy the artefacts to the regular aspnetcore image.
First, we just copy the
csproj file and run
dotnet restore. If you wonder why we don’t copy the whole app at once, it’s because of the way docker caches stages during the build. If it detects the files didn’t change from the last build, it will use the cached image. Project files rarely change, but you probably will have changes in other files. Copying only the project file allows us to use cached stage from the
dotnet restore command, which is time-consuming.
Next, we copy the rest of the application and publish it to the
The second stage uses plain
aspnetcore image and gets build artefacts from the
You can test your new image by running:
docker run -it -p 5000:80 aspdocker
Gitlab has an amazing feature of pipelines. It allows you to run jobs after each commit. You can use them to build your apps, run tests etc. Read more about them in their docs. It’s worth to notice it’s a free feature.
You define your build in the
.gitlab-ci.yml. We will start with something, which will just build our docker image:
This will simply run the
docker build command in the context of our repository. When you commit this file to a GitLab repository, you will notice a green check in the commits list:
Adding tests project
Now, when we have a running CI, which builds our project, it’s time to add support for tests. To do that, I have created an
src directory, where I have moved the
aspdocker project and added another one called
aspdocker.tests. I also had to modify the Docker file a little to support different paths, but in general, to support running tests, I had to add one significant line to
I have added it before the
dotnet publish command so that if tests fail, the processing will stop and for a change, you will get red cross next to your commit:
You can see all changes made here in the GitLab commit.
We now have an ASP.NET Core project, which is built and tested after each commit to the repository. We also have a docker image being built, which in the next post we will push to Docker hub repository and deploy to a Virtual Machine automatically using Docker Cloud.