Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Docker .NET Core - multiple projects in solution

I'm new to Docker and I'm trying to containerise my WebAPI which is part of a solution with multiple projects. This is my folder structure

Solution
    -- RandomPersonPicker.Api
        -- .dockerignore
        -- .dockerfile
    -- RandomPersonPicker.Date
    -- RandomPersonPicker.Domain
    -- RandomPersonPicker.Tests

This is my Docker file:

FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build-env
WORKDIR /app

# Copy csproj and restore as distinct layers
COPY *.csproj ./
RUN dotnet restore

# Copy everything else and build
COPY . ../
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/core/sdk:3.1
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "RandomPersonPicker.Api.dll"]

I run this command from RandomPersonPicker.Api folder

docker build -t aspnetapp

Finally this is my stack trace:

Skipping project "/RandomPersonPicker.Data/RandomPersonPicker.Data.csproj" because it was not found.
  Skipping project "/RandomPersonPicker.Data/RandomPersonPicker.Data.csproj" because it was not found.
  Restore completed in 186.69 ms for /app/RandomPersonPicker.Api.csproj.
/usr/share/dotnet/sdk/3.1.101/Microsoft.Common.CurrentVersion.targets(1875,5): warning : The referenced project '../RandomPersonPicker.Data/RandomPersonPicker.Data.csproj' does not exist. [/app/RandomPersonPicker.Api.csproj]
CompositionRoot.cs(2,26): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'RandomPersonPicker' (are you missing an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
CompositionRoot.cs(3,26): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'RandomPersonPicker' (are you missing an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
Controllers/PersonController.cs(4,26): error CS0234: The type or namespace name 'Data' does not exist in the namespace 'RandomPersonPicker' (are you missing an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
Controllers/PersonController.cs(5,26): error CS0234: The type or namespace name 'Domain' does not exist in the namespace 'RandomPersonPicker' (are you missing an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
Controllers/PersonController.cs(23,39): error CS0246: The type or namespace name 'Person' could not be found (are you missing a using directive or an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
Controllers/PersonController.cs(31,27): error CS0246: The type or namespace name 'Person' could not be found (are you missing a using directive or an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
Controllers/PersonController.cs(15,26): error CS0246: The type or namespace name 'IPersonRepository' could not be found (are you missing a using directive or an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
Controllers/PersonController.cs(17,33): error CS0246: The type or namespace name 'IPersonRepository' could not be found (are you missing a using directive or an assembly reference?) [/app/RandomPersonPicker.Api.csproj]
The command '/bin/sh -c dotnet publish -c Release -o out' returned a non-zero code: 1

I understand the problem, docker doesn't recognise the namespaces of my other projects which gives a compilation error, but I don't know a good way to solve this.

Any help would be appreciated.

like image 576
nick gowdy Avatar asked Jan 27 '20 13:01

nick gowdy


People also ask

Can a Docker container have multiple containers?

It's ok to have multiple processes, but to get the most benefit out of Docker, avoid one container being responsible for multiple aspects of your overall application. You can connect multiple containers using user-defined networks and shared volumes.

Can we have multiple Dockerfiles?

You can set the source for the named context to point to another build target inside the Bake file. This way, you can chain together builds from multiple Dockerfiles that depend on each other and build them with a single command invocation.


Video Answer


1 Answers

In cases like these, I find it easier to put the Dockerfile in the same folder as of the solution (.sln). So if you have multiple projects that have common class libraries, you could easily reference them in your individual docker file. You could either copy everything from root -> root, or mention each project one by one.

Note: This is the root for git and so the Dockerfile becomes a part of the code repo as well.

Dummy Project Example:

ROOT FOLDER
    |--- MultiProject.sln
    |--- MultiProject (solution folder)
        |-- Api.Web (project folder)
            -- Api.Web.csproj
        |-- Api.Mobile (project folder)
            -- Api.Mobile.csproj
        |-- ClassLibrary1
        |-- ClassLibrary2
    |--- Api.Web.Dockerfile
    |--- Api.Mobile.Dockerfile
    |--- .gitignore (*just to highlight the root of source repo*)

Dummy Project Api.Web.Dockerfile:

Note: you might want to restructure the dockerfile to suite your layering style. The one shown in the example has separate build and publish layers.

#Use your choice of image as base. Mine is alpine! 
FROM mcr.microsoft.com/dotnet/core/aspnet:3.1-alpine AS base
WORKDIR /app

FROM mcr.microsoft.com/dotnet/core/sdk:3.1-alpine AS build
WORKDIR /src
COPY . .

RUN dotnet restore "MultiProject/Api.Web.csproj"
WORKDIR "/src/."
COPY . .
RUN dotnet build "MultiProject/Api.Web.csproj" -c Release -o /app/build

FROM build as publish
RUN dotnet publish "MultiProject/Api.Web.csproj" -c Release -o /app/publish

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENV ASPNETCORE_URLS http://*:PORT_NUMBER
ENTRYPOINT ["dotnet", "Api.dll"]

Now, if I want to create another dockerfile for Api.Mobile, it's pretty straightforward from the above example to create one.

like image 113
sandiejat Avatar answered Oct 22 '22 15:10

sandiejat