dockerasp.net-coredocker-composemicroservices

ASP.NET Core microservices web application doesn't work on docker


I desperately need help with a case study project. I created 3 separate projects in order to implement a micro services architecture. I created and implemented client-side and backend-side successfully.

Everything works fine locally. However, when it comes to dockerizing, I completely failed and I don't know why.

First, I was getting an error

Value Cannot Be Null (Parameter ‘s’)

and then I changed the appSettings.json and the dockerfiles. The error has gone but things got more complicated. Because the server is not responsive anymore. I can't even get that error anymore:

Project Folder Structure

One of my dockerfiles:

#See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.

FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
USER app
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["Identity/AdminPanel.Identity.API/AdminPanel.Identity.API.csproj", "Identity/AdminPanel.Identity.API/"]
COPY ["Shared/AdminPanel.Shared/AdminPanel.Shared.csproj", "Shared/AdminPanel.Shared/"]
COPY ["Identity/AdminPanel.Identity.Application/AdminPanel.Identity.Application.csproj", "Identity/AdminPanel.Identity.Application/"]
COPY ["Identity/AdminPanel.Identity.Domain/AdminPanel.Identity.Domain.csproj", "Identity/AdminPanel.Identity.Domain/"]
COPY ["Identity/AdminPanel.Identity.Persistence/AdminPanel.Identity.Persistence.csproj", "Identity/AdminPanel.Identity.Persistence/"]
RUN dotnet restore "./Identity/AdminPanel.Identity.API/AdminPanel.Identity.API.csproj"
COPY . .
WORKDIR "/src/Identity/AdminPanel.Identity.API"
RUN dotnet build "./AdminPanel.Identity.API.csproj" -c $BUILD_CONFIGURATION -o /app/build

FROM build AS publish
RUN dotnet publish "./AdminPanel.Identity.API.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "AdminPanel.Identity.API.dll"]

Here is my docker-compose.yml file:

version: '3.8'

services:
  rabbitmq:
    image: rabbitmq:management
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest
    ports:
      - "5672:5672" 
      - "15672:15672" 
    volumes:
      - "rabbitmq_data:/var/lib/rabbitmq"
    networks:
      - adminpanelnet
  identity_api:
    build:
      context: .
      dockerfile: Dockerfile.Identity
    ports:
      - "5218:80"
    container_name: Identity-api
    depends_on:
      - sqlserver_db
    networks:
      - adminpanelnet
  sqlserver:
    image: mcr.microsoft.com/mssql/server:2022-latest
    environment:
      ACCEPT_EULA: "Y"
      SA_PASSWORD: "Password12*"
    ports:
      - "1499:1433"
    networks:
      - adminpanelnet
    container_name: user_db
  command_api:
    build:
      context: .
      dockerfile: Dockerfile.BuildingConfiguration.Command
    ports:
      - "5228:80"
    container_name: Building_Command-api
    depends_on:
      - mongodb
    networks:
      - adminpanelnet
  query_api:
    build:
      context: .
      dockerfile: Dockerfile.BuildingConfiguration.Query
    ports:
      - "5129:80"
    container_name: Building_Query-api
    depends_on:
      - mongodb
    networks:
      - adminpanelnet
  mongodb:
    image: mongo:latest
    ports:
      - "27017:27017"
    container_name: Building_db
    volumes:
      - mongodata:/data/db
    networks:
      - adminpanelnet
volumes:
  mongodata:
  rabbitmq_data:
networks:
  adminpanelnet:
    driver: bridge

And this is appSettings.json:

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "ConnectionStrings": {
    "UserConnectionString" : "Server=user_db;Database=UserDb;User Id=SA;Password=Password12*;MultipleActiveResultSets=true"
  },

And this is container block of launchSetting.json:

"Container (Dockerfile)": {
      "commandName": "Docker",
      "launchBrowser": true,
      "launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/swagger",
      "environmentVariables": {
        "ASPNETCORE_URLS": "https://+:443;http://+:80"
      },
      "publishAllPorts": true,
      "useSSL": true
}

As I said above, it runs perfectly on my local machine. If you have any opinion, please let me know.Also, I can provide further information if needed. Thanks in advance


Solution

  • launchSetting.json is a Visual Studio file and is not used when running your project without Visual Studio.

    In launchSettings.json, you set the ASPNETCORE_URLS environment variable which causes your container to listen on port 443 and 80. Without that environment variable, your container listens on port 8080.

    To get it to listen on port 443 and 80, you can set the environment variable in your docker compose file, like this

      command_api:
        build:
          context: .
          dockerfile: Dockerfile.BuildingConfiguration.Command
        ports:
          - "5228:80"
        container_name: Building_Command-api
        depends_on:
          - mongodb
        networks:
          - adminpanelnet
        environment:
          - ASPNETCORE_URLS: "https://+:443;http://+:80"
    

    That should get your container to listen on ports 443 and 80 like it does when you run it from VS.

    Ofc, you also need to set the environment variable on your other .NET containers.

    Alternatively, you can let the containers listen on port 8080 which is the default for .NET 8 containers. Then you just need to change the port mappings in your compose file.

    If you're in doubt as to which ports your application is listening on, you can check the logs of the container. ASP.NET prints out what ports it's listening on, when the application starts.