Building a docker image with Gitlab CI and .NET Core
By: Jelle Verheyen
Tags: Gitlab, Docker, Continuous Delivery, Net Core, DevOps

Getting started

I’m going to keep it as simple as possible and will try to explain most things as well as I can so there is not much required except:

Basic knowledge of docker

Basic knowledge of Gitlab CI (see my other post)

Have a basic understanding of how .NET Core projects are built

The project structure we will be working with is:

example

└───src

├───example.sln

└───Example.Presentation

├───Controllers

└───...

It’s just a simple webapi project, generated with dotnet new webapi .

However, by default, dotnet new does not generate a .sln file so make sure you create one in the /example/src/ folder as the pipeline we will be creating assumes there is a solution file in that location.

Setting up our pipeline

Our pipeline will basically build the docker image through a Dockerfile and then push it to our Container Registry on Gitlab.

We will make sure we steer clear of using any keys, credentials, tokens, etc. inside our pipeline to prevent them from being stolen.

Let’s add a .gitlab-ci.yml file in our /src directory and get started.

Our image will be docker:stable :

Next, we will have to define a service named docker:dind . DinD stands for “Docker inside Docker”. We need this as our Gitlab Pipeline is basically a docker container, therefore our docker container will have to spawn another docker container. We call this Dockerception. (no clue if anyone actually says that 🤔).

Defining base image and services

So now with that out of the way, we can get into the actual script.

Before doing any jobs I like running the docker info command which might help when you’re debugging the pipeline:

Run docker info before executing the script

Let’s create a build stage which only runs on the master branch.

Only allow the pipeline to run on master branch

So now for the actual building of the image.

Before we run any docker commands, we want to log into our registry.

We want to be able to do this without directly using credentials inside the pipeline, we will make use of Gitlab’s predefined environment variables. Here, we only make use of a fraction of the available variables but you can find a list of all of them here, the names can change sometimes so make sure your gitlab instance is up to date if it’s self-hosted.

Let’s add a docker login command. We have to pass the URL of the Gitlab registry, our username and password.

Login to the docker registry

As you can see; we’re logging into registry.gitlab.com without providing any hardcoded credentials, exactly as we want!

So now.. building and pushing the image to our registry!

It’s rather simple, really. We just have to run docker build and docker push .

We want to push it to the registry specific to our repository in Gitlab. This is located at registry.gitlab.com/{USER}/{REPOSITORY}, of course, there is an environment variable already defined for all this.

Build and push the image

So we run a build with the -t or —-tag flag, basically giving a name to our image. Then we push it to our Gitlab Registry .

Now, we log out and tell the runner to run the build stage.

Finishing up the pipeline