Задать вопрос
Timur2342
@Timur2342

Как написать Dockerfile для asp.net приложения с такой архитектурой?

Architecture:
Marketplace(direction)
├── server_app(asp.net)
│ ├── server_app.Presentation
│ │ └── server_app.Presentation.csproj
│ ├── server_app.Application
│ │ └── server_app.Application.csproj
│ ├── server_app.Domain
│ │ └── server_app.Domain.csproj
│ ├── server_app.Infrastructure
│ └── server_app.Infrastructure.csproj

├── client_app(react)
Проекты внутри папки server_App как бы типо вроде лука, Presentation зависит от Infrasturcture который от Application и тот уже от Domain. То есть например Infrasturcture берет и nuget пакеты из Application, и вот как я понимаю с этим как раз проблемы, или нет? Это все прекрастно РАБОТАЕТ НЕ В ДОКЕРЕ,
в нем же получаю: => ERROR [server_app build 9/9] RUN dotnet publish server_app.Presentation/server_app.Presentation.csproj -c Development -o /publish

DockerFile(сервера, asp.net):
# .NET Core SDK
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build

# Sets the working directory
WORKDIR /app

ARG ENVIRONMENT=Development
EXPOSE 5183

#COPY *.sln .
COPY ["server_app.Presentation/server_app.Presentation.csproj", "server_app.Presentation/"]
COPY ["server_app.Infrastructure/server_app.Infrastructure.csproj", "server_app.Infrastructure/"]
COPY ["server_app.Domain/server_app.Domain.csproj", "server_app.Domain/"]
COPY ["server_app.Application/server_app.Application.csproj", "server_app.Application/"]

# .NET Core Restore
RUN dotnet restore server_app.Presentation/server_app.Presentation.csproj

# Copy All Files
COPY . .

# .NET Core Build and Publish
RUN dotnet publish server_app.Presentation/server_app.Presentation.csproj -c Development -o /publish

# ASP.NET Core Runtime
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS runtime
WORKDIR /app
COPY --from=build /publish ./

ENV ASPNETCORE_ENVIRONMENT $ENVIRONMENT

ENTRYPOINT ["dotnet", "DDD.Services.Api.dll"]

Docker-Compose.yml:
version: '3.9'

services:
  # ASP.NET Core application
  server_app:
    build:
      context: ./server_app
      dockerfile: Dockerfile
    ports:
      - "5183:5183"
    depends_on:
      - redis
      - mongodb
      - postgres
    environment:
      - ASPNETCORE_ENVIRONMENT=Development
      - DOTNET_USER_SECRETS=/root/.microsoft/usersecrets

  # React application
  client_app:
    build:
      context: ./client_app
      dockerfile: Dockerfile
    ports:
      - "3000:3000"
    stdin_open: true

  # Redis
  redis:
    image: redis:7.2.5
    ports:
      - "6370:6370"

  # MongoDB
  mongodb:
    image: mongo:8.0.4
    ports:
      - "27010:27010"
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=example

  # PostgreSQL
  postgres:
    image: postgres:16.6
    ports:
      - "5430:5430"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: app_db

volumes:
  redis_data:
  mongodb_data:
  postgres_data:


Логи снизу написал как коментарий, не вместились.

Если нужно точнее посмотреть на проект: https://github.com/TimurSkovorodnikov07/Marketplace
Вобще я правильно понял проблему? Дело не совсем только в докере но и в особенной архитектуре. Благодарю за любой адекватный ответ.
  • Вопрос задан
  • 156 просмотров
Подписаться 2 Простой 2 комментария
Пригласить эксперта
Ответы на вопрос 1
@hello_my_name_is_dany
Backend Developer (Node.js, PHP, C#)
У вас проблема в зависимостях
Даже по логу вам говорится:
/app/server_app.Domain/Model/Queries/ProductCategoryCreateQuery.cs(3,17): error CS0234: The type or namespace name 'AspNetCore' does not exist in the namespace 'Microsoft' (are you missing an assembly reference?) [/app/server_app.Domain/server_app.Domain.csproj]


А конкретно проблема в этом
server_app/server_app.Domain/server_app.Domain.csproj
<ItemGroup>
        <Reference Include="FluentValidation">
            <HintPath>..\..\..\..\.nuget\packages\fluentvalidation\11.11.0\lib\net8.0\FluentValidation.dll</HintPath>
        </Reference>
        <Reference Include="Microsoft.AspNetCore.Http.Abstractions">
            <HintPath>..\..\..\..\.nuget\packages\microsoft.aspnetcore.app.ref\8.0.8\ref\net8.0\Microsoft.AspNetCore.Http.Abstractions.dll</HintPath>
        </Reference>
        <Reference Include="Microsoft.AspNetCore.Http.Features">
            <HintPath>..\..\..\..\.nuget\packages\microsoft.aspnetcore.app.ref\8.0.8\ref\net8.0\Microsoft.AspNetCore.Http.Features.dll</HintPath>
        </Reference>
        <Reference Include="Microsoft.AspNetCore.Mvc.Abstractions">
            <HintPath>..\..\..\..\.nuget\packages\microsoft.aspnetcore.app.ref\8.0.8\ref\net8.0\Microsoft.AspNetCore.Mvc.Abstractions.dll</HintPath>
        </Reference>
        <Reference Include="Microsoft.AspNetCore.Mvc.Core">
            <HintPath>..\..\..\..\.nuget\packages\microsoft.aspnetcore.app.ref\8.0.8\ref\net8.0\Microsoft.AspNetCore.Mvc.Core.dll</HintPath>
        </Reference>
        <Reference Include="Microsoft.IdentityModel.Tokens">
            <HintPath>..\..\..\..\.nuget\packages\microsoft.identitymodel.tokens\7.1.2\lib\net8.0\Microsoft.IdentityModel.Tokens.dll</HintPath>
        </Reference>
        <Reference Include="Npgsql.EntityFrameworkCore.PostgreSQL">
          <HintPath>..\..\..\..\.nuget\packages\npgsql.entityframeworkcore.postgresql\9.0.2\lib\net8.0\Npgsql.EntityFrameworkCore.PostgreSQL.dll</HintPath>
        </Reference>
    </ItemGroup>


Вы буквально указали путь к конкретным dll на вашем компьютере, и из-за этого в докер они не попадают, а dotnet restore их просто игнорирует. Эти зависимости должны быть в общем списке, как в блоке ItemGroup ниже этого, но проблема на самом деле куда глобальнее.

Как я понимаю, вы только изучаете DDD, и сделали самую фатальную ошибку в дизайне, Domain не должен отвечать за БД, JWT, модели, DTO и тд. Domain должен концентрировать именно бизнес-сущности и бизнес-логику (Entities & Buisness Services). Application слой уже отвечает за сценарии использования приложения (CQRS или Use Cases, которые оперируют сущностями/сервисами из Domain, а для инфраструктурных моментов использует интерфейсы - dependency inversion). Инфраструктурный слой реализует интерфейсы из Application слоя, например, репозитории бд, http-клиенты и тд, соответственно в нём концентрируется вся работа с БД и другими внешними сервисами. Presentation слой отвечает за представления, это может быть ASP.NET Core API. В таком случае, здесь уже используются модели, JWT, вызов Use Cases из слоя Application, в общем всё, что касается предоставления API.

Это если очень коротко, тема довольно обширная и сложная.
Советую вам почитать:
Мартин Роберт - Чистая архитектура. Искусство разработки программного обеспечения
Эрик Эванс - Предметно-ориентированное проектирование (DDD). Структуризация сложных программных систем

Также именно для C# есть прекрасный пример проекта с использованием подходов CA и DDD, изучите его, необязательно делать всё под копирку, но полезным точно будет.

Удачи Вам!
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы