ASP.NET Core 8 microservices in a single solution using Docker
To work with multiple ASP.NET Core 8 microservices in a single solution using Docker, you can create individual Dockerfiles for each service and orchestrate them using Docker Compose. Docker Compose allows you to define and manage multiple containers (microservices) in a single configuration file (docker-compose.yml
), making it easier to run, scale, and manage multi-container applications.
Here’s a detailed step-by-step guide to containerizing multiple ASP.NET Core 8 microservices in a single solution.
Scenario Overview
Let’s assume you have two microservices in your solution:
- HotelService (ASP.NET Core 8 Web API for hotel-related operations)
- FlightService (ASP.NET Core 8 Web API for flight-related operations)
Each microservice will be built and run as its own container, but Docker Compose will orchestrate them.
Step 1: Create the Solution and Microservices
- Create a new solution:
dotnet new sln -n MicroservicesSolution
cd MicroservicesSolution
- Create the HotelService project:
dotnet new webapi -n HotelService
- Create the FlightService project:
dotnet new webapi -n FlightService
- Add the projects to the solution:
dotnet sln add HotelService/HotelService.csproj
dotnet sln add FlightService/FlightService.csproj
Step 2: Add Docker Support to Each Microservice
For each microservice, you’ll add a Dockerfile
and .dockerignore
file.
HotelService Dockerfile
Navigate to the HotelService
folder and create a Dockerfile
:
# Stage 1: Build the HotelService application
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy the rest of the application code
COPY . ./
RUN dotnet publish -c Release -o out
# Stage 2: Build the runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY /app/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "HotelService.dll"]
Create a .dockerignore
file in the HotelService
folder:
bin/
obj/
FlightService Dockerfile
Navigate to the FlightService
folder and create a Dockerfile
:
# Stage 1: Build the FlightService application
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore
# Copy the rest of the application code
COPY . ./
RUN dotnet publish -c Release -o out
# Stage 2: Build the runtime image
FROM mcr.microsoft.com/dotnet/aspnet:8.0
WORKDIR /app
COPY /app/out .
EXPOSE 80
ENTRYPOINT ["dotnet", "FlightService.dll"]
Create a .dockerignore
file in the FlightService
folder:
bin/
obj/
Step 3: Create the Docker Compose Configuration
At the root of your solution (where the .sln
file is located), create a docker-compose.yml
file. This file will define and configure both microservices.
version: '3.8'
services:
hotelservice:
build:
context: ./HotelService
dockerfile: Dockerfile
ports:
- "5001:80"
networks:
- microservices-network
depends_on:
- flightservice
flightservice:
build:
context: ./FlightService
dockerfile: Dockerfile
ports:
- "5002:80"
networks:
- microservices-network
networks:
microservices-network:
driver: bridge
Explanation:
- services: Defines the two microservices (hotelservice and flightservice).
- build: Specifies the context (project folder) and the Dockerfile for each service.
- ports: Maps the container port (80) to the host machine’s port (5001 for
hotelservice
, 5002 forflightservice
). - networks: Defines a shared network (
microservices-network
) to allow the services to communicate with each other. - depends_on: Ensures that
hotelservice
waits forflightservice
to be ready.
Step 4: Build and Run the Microservices Using Docker Compose
-
Navigate to the root directory of your solution (where the
docker-compose.yml
is located). -
Build the Docker images for both services:
docker-compose build
- Run both microservices:
docker-compose up
The docker-compose up
command will start both microservices in separate containers, map the ports, and handle communication between them.
Step 5: Verify the Microservices
Once the services are up, you can test them by visiting the following URLs:
- HotelService: http://localhost:5001/swagger
- FlightService: http://localhost:5002/swagger
Both microservices should be running and accessible through their respective ports.
Step 6: Access Microservices via Internal Network
The two services are on the same Docker network (microservices-network
). Therefore, you can communicate between services internally using their service names (hotelservice
, flightservice
).
For example, if HotelService
needs to make a request to FlightService
, it would use http://flightservice:80
internally, and similarly, FlightService
can reach HotelService
via http://hotelservice:80
.
Step 7: Stopping and Cleaning Up
- Stop the containers:
docker-compose down
This will stop and remove the containers for both microservices.
- Remove unused images (optional):
docker image prune
This will remove unused Docker images and free up disk space.
Step 8: Push the Microservices Images to Docker Hub (Optional)
If you want to share or deploy the microservices using Docker Hub, follow these steps:
- Login to Docker Hub:
docker login
- Tag the images:
docker tag hotelservice your_dockerhub_username/hotelservice:latest
docker tag flightservice your_dockerhub_username/flightservice:latest
- Push the images to Docker Hub:
docker push your_dockerhub_username/hotelservice:latest
docker push your_dockerhub_username/flightservice:latest
Step 9: Deploy to Cloud (Optional)
You can deploy the Docker images to cloud platforms like Azure App Service for Containers, AWS ECS, or Google Cloud Run. For example, to deploy to Azure:
- Push the images to a container registry (Docker Hub, Azure Container Registry).
- Create an Azure App Service for Containers.
- Configure it to pull your images and deploy them.
Conclusion
By following these steps, you can containerize multiple ASP.NET Core 8 microservices in a single solution and use Docker Compose to manage them. Docker Compose simplifies the orchestration of multiple microservices, allowing you to run them simultaneously, set up networking between them, and manage dependencies.
This setup is highly scalable and can be extended to include databases, caching layers, message queues, etc., in the same docker-compose.yml
file.
Praful's Newsletter 🚀
Join 3900+ Engineers to Level Up Your Skills!
Subscribe to my Software Engineering Deep Dive Series covering ReactJS, Redux, ASP.NET Core, and Clean Architecture. Get 1 insightful email each week to enhance your development journey.