Skip to content

Step-by-Step how-to build & package a .NET Core API as a Docker image, then deploy and spin that image up as Container on Windows, Linux hosts.

Notifications You must be signed in to change notification settings

ersenbasaransen/docker-dotnetcore-api

Repository files navigation

[TOC]

Step By Step Dockerizing .NET Core API

This article demonstrates Step-by-Step how-to build and package a .NET Core API as a Docker image, then deploy and spin that image up as Container on Windows, Linux hosts.

Introduction

What is Docker?

Docker is a "containerization" platform, enabling to package applications into images and run them as “containers” on any platform that can run Docker. So “It works on my local” argument is an empty word with Docker, as Docker images contain everything needed for the app to run.

Containers vs. Virtual Machines

In short;

  • Virtual Machines provide OS Level Virtualisation
  • Containers provide App Level Virtualisation

Virtual Machines vs. Containers

ref https://cloudblogs.microsoft.com/opensource/2019/07/15/how-to-get-started-containers-docker-kubernetes/

Why Use Docker?

  • Portability : Containers are self-contained so they can run on any platform as long as that runs Docker.
  • Scalability : Additional use of “orchestration” can spin up multiple container instances to support increased load.
  • Performance : Containers generally perform better than their VM counterparts.

Image

A docker image is a file that contains the “blueprint” or instructions on how our code is expected to run in Docker, so it includes things like dependencies and instructions on how our app should start.

Container

When an image is “executed to run”, it runs in a container, which is highly portable and independent, (from any other running containers). We can think an image as a class and a container as an object instance of that class.

Overall Dockerizing Flow

deployment-flow

Steps to Execute

Step 0 - Prepare Ingredients

Step 1 - Create the API

1.1 - Create an AspDotNetCore Web API Application

$ dotnet new webapi -n docker-dotnetcore-api

1.2 - Build the Application

$ cd docker-dotnetcore-api
$ dotnet build

1.3 - Run the Application

$ dotnet run

1.4 - See the app in the browser

Open the following URL in a browser

https://localhost:5001/WeatherForecast

See it in the browser

Step 2 - Create Docker Image

To run an app in Docker we need to create an image, we do this by a “Dockerfile”. The Dockerfile defines the image to be created.

  • Define our Dockerfile

  • Using the Docker CLI will issue a “build” command

  • The Docker engine will parse the file

  • The Docker engine will create an image ready for use

2.1 - Create Dockerfile

Add a file named Dockerfile (without any extension) in the root project folder.

Tip : Visual Studio Code has an extension which provides Dockerfile sytnax parsing and IntelliSense

image-20200719113919824

Dockerfile

image-20200719115128542

Line by Line explanation;

  • Line 2: Grab the .NET SDK from Microsoft, so that the Docker Engine can compile the app.

  • Line 3: Specify a dedicated “working directory” where the app will reside in the container

  • Line 6: Copy the .csproj file from our local machine to the working container directory (/app)

  • Line 7: Run dotnet restore to resolve project dependencies (this is done using the .csproj file and retrieving any additional dependencies via Nuget)

  • Line 10: Copy the rest of our project files into our working directory, so we can build the app

  • Line 11: Run the dotnet publish command, specifying that it is a Release build, (-c Release), as well as specifying a folder, (out), to contain the app build dll and any support files & libraries.

    At this stage we have completed building our app

  • Line 14: To keep our image “lean” we retrieve only the aspnet run time image, (as opposed to the full SDK image we used for building), as this is all our app requires to “run”.

  • Line 15: Re-specify our working directory

  • Line 16: Expose the port to use from inside our app

  • Line 17: Copy the relevant files from both the dependency resolution step, (build-env), and build step, (/app/out), to our working directory /app

  • Line 18: Set the entry point for the app, (i.e. what should start), in this case it’s our published .dll using “dotnet”.

.dockerignore

To minimise the footprint of the image, we include a file in the root of our project called: .dockerignore. Add to this file the following contents:

image-20200719120910650

2.2 - Build (Create) Image

Use the following Docker CLI command to build the image by Docker Engine.

$ docker build -t ersenbasaransen/docket-dotnercore-api .

The standard Docker Image naming convention is like this;

<Docker Hub ID>/<Project Name>:<Version>

In my case it is ersenbasaransen/docket-dotnercore-api. In your case give a name that suits you best.

If you omit the version component Docker engine will default it to "latest". You can even omit Docker Hub ID, in this case the image will be generated with a unique id. Bu it is useful to provide the standard naming if this image will be pushed to Docker Hub for deployment.

docker build command will build and tag the image.

2.3 - See the Docker Images in your system

$ docker images

image-20200719122359745

Step 3 - Run the app in Local Docker Container

3.1 - Run On Localhost

$ docker run -p 8080:80 ersenbasaransen/docker-dotnetcore-api

image-20200719122842394

Now the image is running as a container.

The “-p” flag – this is a port-mapping, in this case it’s saying map port 8080 on local PC to port 80 of the container.

3.2 - See the app in the browser

To access the API, we need to use port 8080 as follows:

image-20200719130322937

This will map through to the “Exposed” port 80 specified in the Dockerfile, you should see the same output as before.

3.3 - See the Currently Running Containers

$ docker ps

image-20200719130623783

If your are using VS Code and installed the Docker extension I mentioned above you can also see the running containers as well!

image-20200719130752862

3.4 - Stopping the Container

$ docker stop <ContainerId>

image-20200719131055434

You can also use the VS Code Docker extension to do so!

Step 4 - Push to Dockerhub

The real power of Docker is when we come to deploy it elsewhere, and the ease with which that can be achieved. At this point you need to have a Docker Hub Account.

About Docker Hub?

Docker Hub is a repository where you can find Docker Images, these can be from full-on software vendors, or individuals. Browsing https://hub.docker.com you will see images available for download:

4.1 - Login to Docker Hub

To push an image to your Docker Hub, it is needed to login to Docker Hub, at a command prompt type:

$ docker login

Tip : If you are already signed with Docker Desktop client it will authenticate you with existing credentials.

image-20200719141906210

4.2 - Push the Image to Docker Hub

$ docker push <ImageName>

Now our .NET Core API image is available for the use of others!

image-20200719142147889

Step 5 - Pull to and Run from other hosts

Just to prove the point that containers are fully self-contained, independent deployable apps we will pull and run the image from a machine with nothing installed on it but Docker.

5.1 - Run the Container App

$ docker run -p 8080:80 ersenbasaransen/docker-dotnetcore-api

Docker will first search the image locally and if the image is not found, it will go to Docker Hub, pull down the image and run it. It’s no different from the run command issued against the local image.

5.2 - See the app in the browser

$ docker run -p 8080:80 ersenbasaransen/docker-dotnetcore-api

Browse the URL and the container app will return the JSON response.

http://localhost:8080/WeatherForecast

About

Step-by-Step how-to build & package a .NET Core API as a Docker image, then deploy and spin that image up as Container on Windows, Linux hosts.

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages