In this post I will show how to dockerize an Asp.Net microservice and host it behind an nginx reverse proxy.
This project came out of a need to revamp the way I manage comments on my blog. To avoid spam I have an approval step for comments, so I figured this would be good to opportunity to play with Asp.net Core and Docker. The architecture I will show is a dockerized Asp.Net microservice hosted behind an nginx reverse proxy.
I won’t spend time talking about the Asp.Net code since there is nothing non standard about the C#/Asp.Net code. Instead, let’s start by looking at the Docker part.
In my setup I am creating containers for the microservice as well as the nginx reverse proxy. Let’s start by looking at the Dockerfile for the microservice.
In the Docker I am publishing a release and run the generated dll in a Kestrel process.
Kestrel, the default Asp.Net web server is fast and production ready, but it’s not recommended to expose Kestrel directly to the internet. Instead the recommendation is to put a reverse proxy in front of it to proxy traffic to the underlying Kesteral instance(s). In my case I am configuring nginx to do just that. The nginx Dockerfile can be found below:
For local development I am using Docker-Compose to wire up the containers. See my docker-compose.yml below:
Notice there are two instances of the blog comments microservice. This is overkill for my purposes, but I do it to show that you can do load balancing with nginx as well. Locally the containers are bridged together on a common network, which allows me to use the container names as a host names.
Next we have to configure nginx as the reverse proxy in front of my two instances of the microservice. In addition to the Docker instance of nginx we need a config file (nginx.conf) to define the behavior of the proxy. Let’s take a look at nginx.conf below:
At a high level the config file configures proxying in front of the two instances of my microservice, running on ports 8000 and 9000.
The config also wires up https in front of the microservices. In this example I am using a self signed certificate, but this is just for local testing. I am not a security expert, so I would appreciate any feedback on the security settings in this setup.