How To Implement Micro-Services with Docker in Visual Studio
Requirements:
- Visual Studio (for Mac in my case)
- .Net 3.1
- Docker
- Basic knowledge of ASP.Net Core and Docker
- Sample Project “https://github.com/MohammadTarem/MicroservicesSample”
The solution have 3 stateful services and a WebApp based on BFF pattern. The WebApp handles authentication, security and it is completely stateless. This is a pretty standard micro-service solution with no logic and business. Its sole purpose is to demonstrate the implementation of micro-services to beginners. All stateful services don’t use databases, just in memory repositories.
Customers and Products services follow CRUD architecture and have no business.
The Orders service uses aggregate and repository patterns to separate the business model from data model. Although I didn’t use a data model in this scenario but it is necessary if there was a data store.
All projects in the solution are WepApi projects with default configurations.
The Shoppings WebApp consumes those 3 services and it is the frontend for the backend services. In order to use the stateful services from Shoppings we need to add docker support to all projects by right-clicking on each project and adding docker support. This will add a “Dockerfile” to each project. These are the instructions for docker engine on how to build the image and compile the code inside it. Also a new project with name “docker-compose” will be added to the solution. These are instructions for docker compose to run all images and connect them together. We need to configure the YAML files inside this project to use the stateful services.
YAML is a data serialization format, here is a link on how to write in YAML format “https://www.tutorialspoint.com/yaml/yaml_introduction.htm”.
The Shoppings service depends on other services so we must add the “depends_on” section to the docker-compose.yaml. This ensures that Docker build and run other services before Shoppings. But does not guarantee that the services are up and running.
depends_on:
- customers
- products
- orders
Another important configuration that we need to change, is the port of each service. Docker compose runs all containers inside one VM so in order to expose them to the clients from outside, we need to map a port on the host OS to port 80/443. But services inside the VM can access each other on port 80/443. I added these changes to docker-compose.override.yaml under port section of each service.
ports:
- "4000:80"
- "4001:443"
This means that port 4000 of the host OS must be mapped to port 80 of the container. The service will be exposed on port 4000 for http and 4001 for https to the clients.
Finally, we must provide the address of stateful services to Shoppings. I send them as environment variables to Shoppings service.
environment:
- CUSTOMERS=http://customers:80
- PRODUCTS=http://products:80
- ORDERS=http://orders:80
Docker resolves the names of the services to proper IP inside its virtual network.
Visual Studio does all the heavy work behind the scene. To run all services just select docker-compose project as startup project and run the solution. Visual studio uses docker commands to download base images (if necessary), build the services and compose them up.
Mohammad Tarem
Cheers!