Docker containers are the buzzword these days. Container technology offers a new, easy and simplified approach to deploy apps. Containers provide good degree of isolation, yet offers the luxury of leveraging host system’s hardware efficiently. If you are very new to containers, head to Docker site and get a hang on how containers work. In this post, I will show how we can build an image using dotnet core that runs on a docker container.

Docker images are primarily linux based ones. So, whatever image we build using dot net core will be running on a linux platform. Since dotnet core is a truly cross platform framework, we now have the ability to run them on docker containers. That said, we can use docker engine on Windows/macOS/Linux based systems to build the image. I will be using Docker for Mac to build images and run the containers.

Step 1 : Install Docker for Windows/Mac/Linux

Depending on your machine, you can follow the instructions from Docker site to install the  appropriate component.

Once the installation is complete, the docker documentation provides detailed guidelines on verifying the installation and using common commands.

Step 2 : Create a new dot net core app

Creating a new dot net core app is as easy as running the command dotnet new . This should create a project with two files

  • Program.cs – containing the entry point to the app
  • Project.json – containing the application metadata

To make sure the application is running fine, do a dotnet restore – to restore the dependent packages and dotnet run – to execute the app, you should be seeing Hello World!as the output.

Step 3 : Add a Dockerfile

Docker engine understands the instructions in this file and use them to build the image. There are a few built in commands that we can use in our dockerfile. Note that the file name should be dockerfilewithout any extension. All we need are the below 4 lines to build the image.

FROM microsoft/dotnet:latest
COPY /app /app
ENTRYPOINT dotnet hwapp.dll

FROM microsoft/dotnet:latest – indicates that the current image we are building has to be built on top of the existing image  “microsoft/dotnet:latest” (i.e, based on the latest version of dotnet image from Microsoft)

WORKDIR /app – indicates the working directory for this app.

COPY /app /app – indicates to copy the /app folder from the current application in the context to the /app folder within the image.

ENTRYPOINT dotnet hwapp.dll – indicates the entrypoint for this image, i.e, what should get executed when someone runs this image. This would make sure the app when run in a docker container produces the same output as it does when ran via dotnet run

Now that we have the instructions in place, its time to run the commands and build the image.

Step 4 : Build the image

This requires some series of command execution. First is to get the “/app” directory within the application directory. That can be done by using publish command of dotnet cli. Run the below two commands (from the root directory of the project) to create the app directory

dotnet build
dotnet publish -c release -o app

Though this can be accomplished by simply running the publish command alone, as that does the build internally. Now that app folder is available, we can run the docker command and build the image.

docker build -t hello-world-core .

-t is to specify the tag for this image and . specifies the current context from where the dockerfile can be found. The output of the command should look like below:

Sending build context to Docker daemon 368.1 kB
Step 1 : FROM microsoft/dotnet:latest
latest: Pulling from microsoft/dotnet
6a5a5368e0c2: Pull complete
7b9457ec39de: Pull complete
ff18e19c2db4: Pull complete
7b5d77df24dd: Pull complete
aa048ddaaa8f: Pull complete
7b2ee6d027e6: Pull complete
Digest: sha256:40a4e8cc6192ce04ab6c0c8f1888798a46690fb42890b0eec28cde2489e7d709
Status: Downloaded newer image for microsoft/dotnet:latest
---> 9037d65411f1
Step 2 : COPY /app /app
---> 876b56f26a66
Removing intermediate container 1be62bbdac0b
Step 3 : WORKDIR /app
---> Running in dc7c513f212e
---> 6397a85eac27
Removing intermediate container dc7c513f212e
Step 4 : ENTRYPOINT dotnet hwapp.dll
---> Running in a8e9a8adcca3
---> 96908e147c78
Removing intermediate container a8e9a8adcca3
Successfully built 96908e147c78

To make sure image is successfully built, you can run the below command

docker images
hello-world-core latest 96908e147c78 About a minute ago 541.8 MB

Step 5 : Run the application in container

To run the application, execute the below command

docker run hello-world-core
Hello World!

Hurray! we just built and deployed our app into a docker container 🙂 What this command has actually done is

  1. Instanced a new container with the image “hello-world-core”
  2. Ran the application specified as entry point in the image.
  3. Torn down the container after execution

i.e, Within my Mac machine, docker created a linux based container that booted the linux system, ran the dotnet core app hello-world, and tore it down. All of these happened within seconds! That’s the  power of containers! This definitely opens up a lot of opportunities for us to get more efficient with the CI/CD, scaling the app etc., More on those in a future post!