How to Develop Microservices Using .NET Core & Docker

With increasing business demands, we now develop very large and complex projects that take more time to build and deploy. Whenever QA reports any issue, we need to debug or fix it and then deploy the whole code. To reduce these complexities, most organizations are moving towards Microservices development and Docker for easy deployment and smooth service running.

In this blog post, I’ll explain why we should use Microservices, .NET Core, and Docker, and I will show both the step-by-step development of microservices using .NET Core and its run using Docker with different case studies.

Throughout the article, I’ll answer a few key questions, including:

  • What is the software required for Windows?
  • Why should we use microservices instead of a monolithic approach?
  • Why should we use .NET Core?
  • Why should we use Docker?

I’ll also explain how to create microservices using .NET Core, as well as show how to build and run it using Docker through real-life case study examples:

  • Case 1: Run the same image in multiple containers
  • Case 2: Manage different Containers
  • Case 2: Run the same image in multiple environments
  • Case 3: Tag and Run image with different versions

What is the software required for Windows?

  • Windows 10 is required for Docker installation.
  • Visual Studio 2017 has built-in support for Docker, so this is highly recommended.
  • .NET Core SDK
  • Docker for Windows
  • Docker Tools

Why should we use microservices instead of a monolithic approach?

Microservices is an approach to develop small services that each run in its own process. We should develop microservices instead of one service (a monolithic approach) for a multitude of benefits, including:

  • Microservices are smaller in size
  • Microservices are easier to develop, deploy, and debug, because a fix only needs to be deployed onto the microservice with the bug, instead of across the board
  • Microservices can be scaled quickly and can be reused among different projects
  • Microservices work well with containers like Docker
  • Microservices are independent of each other, meaning that if one of the microservices goes down, there is little risk of the full application shutting down

Why should we use .NET Core?

.NET Core is a great development tool for many reasons, including that it’s open source and is very helpful in developing high-performance and scalable systems. It supports cross-platform runtime, so if you create a service using .NET Core, it can be run on any platform. .NET Core is also helpful for faster development, as well as supporting built-in dependency injection and a cloud-based environment configuration. .NET Core also has Docker support, though it’s important to note that it does not support SQL Server Version 2005.

Why should we use Docker?

Docker is a tool that makes it easier to create, deploy, and run applications by using a containerization approach. These containers are lightweight and take less time to start than traditional servers. These containers also increase performance and lower cost, while offering proper resource management. Another benefit to using Docker is that you no longer need to pre-allocate RAM to each container.

How to create a new microservice using .NET Core and then build and run it using Docker

Step 1: Create a microservice (.NET Core WebAPI) with Docker support as shown below:

Select “ASP.NET Core Web Application (.NET Core)” from the drop-down menu.

Select the “Enable Docker Support” option.

The following Application Structure will be created along with “Docker File.”

 

Dockerfiledocker-compose.override.yml
This file is the entry point for running any Docker application.

It is used to build an image of the application’s published code in “obj/Docker/publish.”

This file is used when running an application using Visual Studio.

Step 2: Update Dockerfile and docker-compose.override.yml as shown below and build the application. 80 is the default Docker container port, so you should update it to a different port number, like 83.

Dockerfiledocker-compose.override.yml

Note: You can run the application using both Visual Studio and the Docker command line.

Step 3: Run the application using Visual Studio.

Step 4: Run the application using Docker Command. Open Application folder from command prompt and check the existing images using Docker images and running containers using Docker PS.

As you can see, there is no running container. So, run the following commands to create build:

To restore packages: dotnet restore

To publish the application code: dotnet publish -o obj/Docker/publish

To build the image: docker build -t imagename

Now, check the newly created image “coreappimage” in Docker Images.

Run the image in a container: docker run -d -p 8001:83 –name core1 coreappimage

Check the running container: Docker PS

Now the application is running in the Core1 container with the URL http://localhost:8001.

Case 1: Run the same image in multiple containers

We can run the same image in multiple containers at the same time by using:
docker run -d -p 8002:83 –name core2 coreappimage
docker run -d -p 8003:83 –name core3 coreappimage

Check the running containers by using Docker PS.

We can see that there are 3 containers running for the same image at 8001, 8002, and 8003.

http://localhost:8001http://localhost:8002http://localhost:8003

Case 2: Manage Containers: Stop/Start/Remove Containers

Stop container:

We can stop any running containers using “docker stop containerid/containername”
docker stop core1.

Note: Now this container core1 will be listed in the “All Containers” list but not in the running containers list.

Check running containers: docker ps:

Check all containers: docker ps -a

Note: Now the container running on http://localhost:8001 will not work.

 

Start Container:

We can start a stopped container using “docker start containerId/containername”

=> docker start core1

Note: Now it will be listed in the running containers list and http://localhost:8001 will start working.

Remove Container:

We can remove any stopped container, but then we will not be able to start it again.

So first we should stop the container before removing it:

=> docker stop core1

=> docker rm core1

Now this container will not be listed on the containers list:

Case 3: Run the same image in multiple environments

First, add transformations for different environments:

Step 1Create the following AppSetting class and key.
Step 2In startup.cs, register IAppSettings to

resolve dependency.

Step 3Add two AppSettings json for QA/Production environment.“appsettings.Production.json”

“appsettings.QA.json”

Step 4Read this EnvKey Value in ValuesController.

Now, create an image by repeating the same steps (dotnet restore, dotnet publish and docker build).

Note: If we do not specify the environ while running the container, it will take “Production” by default.

=> docker run -d -p 8004:83 –name core4 coreappimage

 

Run Image in a specific environment:

=> docker run -d -p 8005:83 –name core5 –env ASPNETCORE_ENVIRONMENT=Development coreappimage

 => docker run -d -p 8006:83 –name core6 –env ASPNETCORE_ENVIRONMENT=QA coreappimage

=> docker ps

Case 4: Tag and Run image with different versions

Image tag is a version that allows you to differentiate different code base images. By default, every image is created with the tag “latest,” so whenever we create a new image for the updated code, it then replaces the existing image with same tag. This means that if we want to maintain the updated and previous code base images, we should tag them.

Let’s remove all running containers:

=> docker stop core2 core3 core4 core5 core6

=> docker rm core2 core3 core4 core5 core6

=> docker ps  (Note: There is no running container here.)

Step 1: Tag previously created image “coreappimage” with version 1.0.

Syntax: docker tag imagename imagename :version

=> docker tag coreappimage coreappimage:1.0

Step 2: Update the application to apply the authorization filter so that the API will be accessible using the Authorization Header “auth_key:core.”

Add CustomAuthorizeFilter class
Apply globally in Startup.cs

Create an image with 1.1 tag/version.

We can see two versions of the image under “coreappimage” 1.0 and 1.1.

Run image with version 1.0:

=> docker run -d -p 8006:83 –name core1 –env ASPNETCORE_ENVIRONMENT=QA coreappimage:1.0

Run image with version 1.1:

docker run -d -p 8002:83 –name core2 –env ASPNETCORE_ENVIRONMENT=QA coreappimage:1.1

 
This will be accessible only by passing the Authorization header auth_key:core.

Note: Here we can see that for version 1.0 of the image, no authorization is required for the API or values. However, for version 1.1 of the image, we have to pass an authorization header. 

To test this out yourself, you can download CoreAppWithDocker.zip with the Sample application source code from this link: https://drive.google.com/open?id=17UTFOm5D_py4rk7sjOPQ3nQxpraLCB1Z

Rakhi Shrivastava

Rakhi Shrivastava

Rakhi Shrivastava is AWS Certified Solution Architect at 3Pillar Global in our Noida office. She has expertise in Microservices ,AWS and Single Sign-On (SSO) security implementation using OAuth and Identity Server4. She loves challenging work and is keen on learning new technologies.
She also loves sharing her knowledge and created below technical learning channel
https://www.youtube.com/channel/UCrClzbxFNa7eDULoDqh46MA

38 Responses to “How to Develop Microservices Using .NET Core & Docker”
  1. Rakesh Kumar on

    When executing the build command i have got the following error message.

    docker build coreimage
    unable to prepare context: path “coreimage” not found
    PS E:\Rakesh_Kumar\Samples\DockerQuickStart\DockerQuickStart>

    Reply
    • Rakhi Shrivastava on

      Please use the correct command to build and I hope you are running this command on your application folder where DockerFile exists that’s why you have to use (.) in end of command.
      command: docker build -t coreimage .

      Reply
  2. shishir on

    this is a very good head-up tute. but more useful if add some link – how to install docker/docker tool box in windows.

    Reply
  3. Sandeep on

    Hello Rakhi…

    Do you provide training also for the this kind of stuff..

    Please call me at 9711537214

    Reply
  4. Saurabh on

    Great article . Got good basic understanding of hosting .Net core in docker. It worked nice after following all steps. Like to see more article. Thanks

    Reply
  5. Simal Patel on

    Hi Rakhi,

    Do I really need Docker to create microservices using.Net core?

    I am trying to create microservices which will run in its own container. What would be better approach using .Net Core 2.0?

    I will appreciate your help.

    Reply
  6. pavani on

    can’t we run the application remotely

    Reply
    • Rakhi Shrivastava on

      If you are talking about Sample application(CoreAppWithDocker.zip) to run remotely then No.
      You have to set Docker at your system and then build image and run image.

      Reply
  7. Ninos Denkha on

    Thank you for the excellent article!

    Reply
  8. sachin thamke on

    hi
    I need to start the micros-services , need help for below given points
    1. Db Level authorization
    2. Exception handing
    3. how send bulk data as input to web services
    4. best practices

    Reply
    • Rakhi Shrivastava on

      1. Db Level authorization
      In web service,we implement authentication/authorization for service and at DB level we should also implement authorization so that only authorized users can access service/DB.

      2. Exception handing
      Global exception handling must implemented

      3. how send bulk data as input to web services
      Bulk data can be posted as input to service.

      4. best practices :
      I will post another article on Best practices but for now below are some:
      a. There must be one service per feature.
      b. There must be one endpoint per task
      c. Service must be independent from another service.
      d. Apply proper rest conventions
      e. Apply input validation
      f. Apply proper exception handling
      g. Implement Authentication
      h. Implement Logging

      Reply
  9. Sam on

    docker run -d -p 8001:83 –name core1 coreappimage

    unknown shorthand flag: ‘n’ in -name

    Reply
  10. srinivas on

    C:\iworkspace\FSL DEV\MicroServices\MicroServicesWithDockerTest\DockerTest\DockerTest>docker build -t dockertestimage .
    Sending build context to Docker daemon 2.923MB
    Step 1/17 : FROM microsoft/aspnetcore:2.0-nanoserver-sac2016 AS base
    Get https://registry-1.docker.io/v2/: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

    Reply
  11. Tushar on

    Very Nice article.
    Brief and clear explanation.

    Reply
  12. Pranita Shaha on

    I simply wanted to thank you so much again. Thanks for sharing this valuable information on HOW TO DEVELOP MICROSERVICES USING .NET CORE & DOCKER.
    I hope you will keep sharing more such informative articles.
    I would like to know more about ASP.NET CORE PITFALLS .

    Reply
  13. Donny Lai on

    It is an excellent, clear, and clean article of Dockers with .Net Core. Thanks.

    Reply
  14. madan on

    Hello Rakhi !! Thanks for Article.. More Informative n Inspiration ..Keep going …

    Reply
  15. Dot Net Programmer on

    ————————————————-
    Enjoyed reading the article above, really explains everything in detail about HOW TO DEVELOP MICROSERVICES USING .NET CORE & DOCKER. the article is very interesting and effective.

    Reply
  16. Rakhi Shrivastava on

    Hi All,
    I’ve created my technical youtube channel for learning sessions as below. You can learn step by step:
    https://www.youtube.com/playlist?list=PLcm5D_sGamD4ro3TdSIX6a9l5d8Nq7pi9

    Please let me know if you have any query.

    Reply
  17. padmashree on

    Very Nice blog..Thank you for this as I am beginner in this field .This will be very useful for me

    Reply
  18. Nirman Doshi on

    Very nice article, and a good starting point for someone who need to develop services in .NET Core and run in Docker containers. From there, one needs to take it forward to using containerization platform (such as, Docker Swarm or Kubernetes) to manage/ scale up or down containers.

    Reply
  19. Bill on

    Did not understand something…

    Reply
  20. Online Dot Net Training on

    Thank you for this information..I am beginner in this field. This information is really very helpful for me..
    keep Sharing..
    thank you once again

    Reply
  21. Ahad Zubair on

    Hi Rakhi, the way you explained the article is really commendable. However, I have a few very simple questions, if you could answer then it would be handy assistance:

    a) Can I build a container or create images on Windows 10 HOME edition? If yes then how because I am getting the error “image operating system “windows” cannot be used on this platform” ……..?
    b) For creating a microservices article, is it necessary to create API based projects? Also, what are the steps for converting an asp.net N-tier (obviously non-MVC) application to the container based architecture?
    c) How it would work with VSTS 2017 as a CI/CD pipeline for the automated build deployments on target servers?
    Regards

    Reply
  22. Nirmala on

    Hi Rakhi,

    it is very good articles and very useful. i need help on ADFS using outh2. i have implemented adfs using Oauth2 with help of iink -https://github.com/nordvall/TokenClient/wiki/OAuth-2-Authorization-Code-grant-in-ADFS. But i got error “Invalid Grant” after getting the code and post to ext method. Please share link if you have solution on this.

    Reply
  23. Frederico Breno on

    Dude, nice post. Thank you. It helped me a lot.

    Reply
  24. Bilal Mubeen on

    Its just a web Api project as a single microservice that is running on docker. There is no concept of having a microservice. You didn’t even tried to create another microservice which interacts to each other also the way you did the authentication is totally for a single service based. Stop writing such kind of articles. Get some proof of concepts and then write an article.

    Reply
  25. Saurabh Jain on

    Dear Rakshi,

    it’s a very a good article for POC.
    But if i run .net core app/api into docker container it’s running only on mysystem means the container IP is not expose publicly so for that what should i use that other can use my application too.

    Thanks !!!

    Reply
  26. Mukesh Kumar on

    Hello Rakhi,
    I appreciate your knowledge. It is very good and knowledgeable article.

    Reply
  27. Sangeeta on

    Hi Rakhi,

    Thank you for this article. Its very nice and informative. It helped me alot.
    Hope to see some more articles from you.

    Reply
Leave a Reply