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.
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.
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.
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.
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*)
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With