Chris's coding blog

.NET Core continuous integration and deployment with Gitlab, Docker, Kubernetes and Google Cloud

February 01, 2017

Over the past few months I’ve put Roadkill on hold in my free time, to get some .NET core projects working inside Docker. They’re mostly sandbox websites for exploring the tech stack, and are hosted privately in Gitlab. Gitlab gives you a decent CI server for free, which works really well with CI and deployment of .NET core apps (both websites and console apps).

How the build works

As .NET core runs in Linux, you no longer have to worry about spinning up an over-powered Windows server. What’s more you can do it all inside a Docker container. I plan to do a series of posts on my learnings with .NET core and Kubernetes, in the meantime below is the YAML build definition build I used. It does the following:

  1. Build and publish (publish is just creating a clean bin folder with assets) the .NET Core app in release mode
  2. Build the Docker image in the repository: docker build -t gcr.io/my-kube-project/...
  3. The tag I use for each Docker image is the short Git commit ID.
  4. Finally push to the Google Cloud Docker registry.

One final step you could easily add is performing a kubectl edit deployments/... to update the Docker image to the latest tag, but it’s not in the YAML build definition file.

What does the app do?

The app has a website, and then a Google Cloud Pub/Sub part that is used for updating data that the website uses periodically. The Pub/Sub part is a publisher and a poller-based subscriber. I tried using push but Google Cloud had a habit of denial of servicing my endpoint, even with throttling enabled inside Nginx.

All three bits are Docker containers running as seperate pods inside a Kubernetes cluster.

How can I change the file so it works with Bitbucket Pipelines/Travis/Appveyor/CI-service XYZ

You could convert it really easily to another build service YAML format. Appveyor wouldn’t make much sense, but other services would be trivial to do.

Source

# http://docs.gitlab.com/ce/ci/docker/using_docker_build.html#using-the-gitlab-container-registry
# The docker tag is the first 6 letters of the Git commit id
job_build_dotnet:
stage: build
image: microsoft/dotnet:latest
script:
- dotnet restore
- dotnet publish src/MyProject.Web -c Release
artifacts:
expire_in: 12 hrs
paths:
- src/MyProject.Web/bin/Release/netcoreapp1.1/publish/
job_build_docker:
stage: deploy
image: docker:latest
services:
- docker:dind
script:
- export DOCKER_VERSION=$(echo "$CI_BUILD_REF" | cut -c 1-6)
- echo "$GOOGLE_AUTH_JSON" > google-cloud.json
- cd src/MyProject.Web && docker build -t gcr.io/my-kube-project/MyProject-web:$DOCKER_VERSION .
- cd ../../ && docker login -e 1234@5678.com -u _json_key -p "$(cat google-cloud.json)" https://gcr.io
- docker push gcr.io/my-kube-project/MyProject-web:$DOCKER_VERSION
dependencies:
- job_build_dotnet
view raw .gitlab-ci.yml hosted with ❤ by GitHub

continuous-integration.net-coregitlabdockerkubernetesgoogle-cloud

Chris Small

I'm Chris Small, a software engineer working in London. This is my tech blog. Find out more about me via GithubStackoverflowResume