11

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.

2 Answers 2

16

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Excelent!!! Worked for me
1

try to do the build and publish steps in different steps. also you need to copy the files after restore and build

somthing on the lines of below

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 *.csproj
COPY . .
RUN dotnet build -c Release

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

# 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"]

1 Comment

I've tried your solution and I'm still getting the same error. Aren't I supposed to build the projects based on the dependencies then the web api last?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.