Monday, August 24, 2020

Multi Container App with Docker-Compose and Visual Studio

In this post, let's see how we can set up a Multi Container App with Docker-Compose and Visual Studio. I am assuming you have a basic understanding of Docker.

To start off, I have following set of projects in my solution.

Solution

I have 3 microservices, Customers.API, Orders.API and Products.API. Then I have a BFF Service (Back end For Front end, some call aggregate service etc) and then a Blazor Web App. Blazor web app will be calling the BFF service, and then the BFF Service will be calling Customers/Orders/Products APIs as required.

Then I can add Container Orchestrator Support easily for each of the projects by right-clicking on each project, Add -> Container Orchestrator Support.

Container Orchestrator Support
Then it's asking which Orchestrator to use. I am selecting Docker Compose.

Add Container Orchestrator Support
And I am going to be on Linux.
Docker Support Options

Once I do that, Visual Studio will create a Dockerfile in each of the projects and add a new project named docker-compose to the solution.

docker-compose project

There I have docker-compose.yml which has the base configuration and docker-compose.override.yml to override its configuration for local development.

docker-compose.yml

version: '3.4'

services:
  customers-api:
    image: ${DOCKER_REGISTRY}/longhorn/customers/api
    build:
      context: .
      dockerfile: src/Services/Customers/Longhorn.Customers.Api/Dockerfile


  orders-api:
    image: ${DOCKER_REGISTRY}/longhorn/orders/api
    build:
      context: .
      dockerfile: src/Services/Orders/Longhorn.Orders.Api/Dockerfile


  products-api:
    image: ${DOCKER_REGISTRY}/longhorn/products/api
    build:
      context: .
      dockerfile: src/Services/Products/Longhorn.Products.Api/Dockerfile


  gateways-bff:
    image: ${DOCKER_REGISTRY}/longhorn/gateways/bff
    build:
      context: .
      dockerfile: src/Gateways/Longhorn.Web.Bff/Dockerfile
    depends_on:
      - customers-api
      - orders-api
      - products-api


  web-blazor:
    image: ${DOCKER_REGISTRY}/longhorn/web/blazor
    build:
      context: .
      dockerfile: src/Web/Longhorn.Web.Blazor/Dockerfile
    depends_on:
      - gateways-bff
So here I have done some changes to the docker-compose.yml file created by Visual Studio to configure container dependencies. So the containers will spin up based on their dependencies.

Then I have docker-compose.override.yml file modified to configure it's environment variables. Because Blazor Web App needs to know BFF Service URL and BFF Service needs to know Customers/Orders/Products URL.

docker-compose.override.yml
version: '3.4'

services:
  customers-api:
    image: ${DOCKER_REGISTRY-}longhorn/customers/api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80      
    ports:
      - "6001:80"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

  orders-api:
    image: ${DOCKER_REGISTRY-}longhorn/orders/api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
    ports:
      - "6002:80"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

  products-api:
    image: ${DOCKER_REGISTRY-}longhorn/products/api
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
    ports:
      - "6003:80"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

  gateways-bff:
    image: ${DOCKER_REGISTRY-}longhorn/gateways/bff
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - urls__customersApi=http://customers-api
      - urls__ordersApi=http://orders-api
      - urls__productsApi=http://products-api
    ports:
      - "6004:80"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro

  web-blazor:
    image: ${DOCKER_REGISTRY-}longhorn/web/blazor
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - ASPNETCORE_URLS=http://0.0.0.0:80
      - urls__bffService=http://gateways-bff
    ports:
      - "6005:80"
    volumes:
      - ${APPDATA}/ASP.NET/Https:/root/.aspnet/https:ro
Note: we can just use the service name as the URL, that's just a nice feature. And from the code, I can just use Urls passed in. For example:
Environment Variables
You can change the docker-compose project properties to set the startup.
docker-compose startup
And then hit Debug on docker-compose.
Output
And everything is working just fine, Blazor Web App calls the BFF Service, and BFF Service calls the Microservices.

And Visual Studio shows all the containers in the solution and all it's details including logs which is just super awesome.
Container Tools
Hope this helps.

Happy Coding.

Regards,
Jaliya

No comments:

Post a Comment