So I have a .NET 6 solution structured like so:
MySolution
|
-- RecipeManagement
|
---- src
|
------ RecipeManagement
|
-------- RecipeManagement.csproj
|
-------- Dockerfile
|
---- tests
|
------ RecipeManagement.IntegrationTests
|
-------- RecipeManagement.IntegrationTests.csproj
|
------ RecipeManagement.UnitTests
|
-------- RecipeManagement.UnitTests.csproj
|
-- SharedKernel
|
---- SharedKernel.csproj
|
-- dockercompose.yaml
I'm having trouble getting my Dockerfile to properly reference my SharedKernel
class project.
Without the SharedKernel, something like this usually works fine:
dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY ["RecipeManagement.csproj", "./"]
RUN dotnet restore "./RecipeManagement.csproj"
# Copy everything else and build
COPY . ./
RUN dotnet build "RecipeManagement.csproj" -c Release -o /app/build
FROM build-env AS publish
RUN dotnet publish "RecipeManagement.csproj" -c Release -o /app/out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=publish /app/out .
ENV ASPNETCORE_URLS=https:// :8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "/app/RecipeManagement.dll"]
compose:
version: '3.7'
services:
recipemanagement-db:
image: postgres
restart: always
ports:
- '52450:5432'
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=dev_recipemanagement
volumes:
- recipemanagement-data:/var/lib/postgresql/data
recipemanagement-api:
build:
context: ./RecipeManagement/src/RecipeManagement
dockerfile: Dockerfile
ports:
- "52451:8080"
environment:
ASPNETCORE_ENVIRONMENT: "Development"
DB_CONNECTION_STRING: "Host=recipemanagement-db;Port=5432;Database=dev_recipemanagement;Username=postgres;Password=postgres"
volumes:
- ~/.aspnet/https:/https:ro
volumes:
recipemanagement-data:
But, once I try to bring in the SharedKernel, it gets unhappy. Note the differences:
- Updated
context
anddockerfile
path in compose - Updated
Copy csproj and restore as distinct layers
section to account for new context and project
dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY ["RecipeManagement/src/RecipeManagement/RecipeManagement.csproj", "RecipeManagement/"]
COPY ["SharedKernel/SharedKernel.csproj", "SharedKernel/"]
RUN dotnet restore "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj"
# Copy everything else and build
COPY . ./
RUN dotnet build "RecipeManagement.csproj" -c Release -o /app/build
FROM build-env AS publish
RUN dotnet publish "RecipeManagement.csproj" -c Release -o /app/out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=publish /app/out .
ENV ASPNETCORE_URLS=https:// :8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "/app/RecipeManagement.dll"]
compose:
version: '3.7'
services:
recipemanagement-db:
image: postgres
restart: always
ports:
- '52450:5432'
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=dev_recipemanagement
volumes:
- recipemanagement-data:/var/lib/postgresql/data
recipemanagement-api:
build:
context: .
dockerfile: RecipeManagement/src/RecipeManagement/Dockerfile
ports:
- "52451:8080"
environment:
ASPNETCORE_ENVIRONMENT: "Development"
DB_CONNECTION_STRING: "Host=recipemanagement-db;Port=5432;Database=dev_recipemanagement;Username=postgres;Password=postgres"
volumes:
- ~/.aspnet/https:/https:ro
volumes:
recipemanagement-data:
The result here being that it can't find the file for some reason:
------
> [build 5/8] RUN dotnet restore "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj":
#13 0.374 MSBUILD : error MSB1009: Project file does not exist.
#13 0.374 Switch: RecipeManagement/src/RecipeManagement/RecipeManagement.csproj
------
Potentially of note, if i just adjust the context and dockerfile path with the original project that doesn't have a shared kernel, i start getting yelled at about my test projects not being included
Edit
In response to the answer from @Paolo, I tried both of the below dockerfiles running docker build -f RecipeManagement/src/RecipeManagement/Dockerfile .
from my root MySolution
directory and get the same error. I've tried a few different dockerfile iterations. see two below:
one iteration:
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY ["RecipeManagement/src/RecipeManagement/RecipeManagement.csproj", "RecipeManagement/"]
COPY ["SharedKernel/SharedKernel.csproj", "SharedKernel/"]
RUN dotnet restore "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj"
# Copy everything else and build
COPY . ./
RUN dotnet build "RecipeManagement.csproj" -c Release -o /app/build
FROM build-env AS publish
RUN dotnet publish "RecipeManagement.csproj" -c Release -o /app/out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=publish /app/out .
ENV ASPNETCORE_URLS=https:// :8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "/app/RecipeManagement.dll"]
second iteration:
FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base
WORKDIR /app
ENV ASPNETCORE_URLS=https:// :8080
EXPOSE 8080
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build
WORKDIR /src
COPY ["RecipeManagement/src/RecipeManagement/RecipeManagement.csproj", "RecipeManagement/"]
COPY ["SharedKernel/SharedKernel.csproj", "SharedKernel/"]
RUN dotnet restore "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj"
COPY . .
WORKDIR "/src/RecipeManagement"
RUN dotnet build "RecipeManagement.csproj" -c Release -o /app/build
FROM build AS publish
RUN dotnet publish "RecipeManagement.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "RecipeManagement.dll"]
** Update: if i change
RUN dotnet restore "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj"
to
RUN dotnet restore "RecipeManagement/RecipeManagement.csproj"
in option 2 it gets past the error, but wants to build all my tests
CodePudding user response:
You can achieve the desired behavior by using docker build
with the -f
option to build the image.
From the MySolution
folder, you can run:
docker build -f RecipeManagement/src/RecipeManagement/Dockerfile .
This command will build the Dockerfile from the nested folder with the current directory, MySolution
, as the root of the build context.
CodePudding user response:
okay, so i updated it to have the copy paths mirror my solution paths and that seemed to do the trick! also had a typo in http vs https but that's seprate :-)
FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app
# Copy csproj and restore as distinct layers
COPY ["RecipeManagement/src/RecipeManagement/RecipeManagement.csproj", "./RecipeManagement/src/RecipeManagement/"]
COPY ["SharedKernel/SharedKernel.csproj", "./SharedKernel/"]
RUN dotnet restore "./RecipeManagement/src/RecipeManagement/RecipeManagement.csproj"
# Copy everything else and build
COPY . ./
RUN dotnet build "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj" -c Release -o /app/build
FROM build-env AS publish
RUN dotnet publish "RecipeManagement/src/RecipeManagement/RecipeManagement.csproj" -c Release -o /app/out
# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=publish /app/out .
ENV ASPNETCORE_URLS=http:// :8080
EXPOSE 8080
ENTRYPOINT ["dotnet", "/app/RecipeManagement.dll"]
version: '3.7'
services:
recipemanagement-db:
image: postgres
restart: always
ports:
- '52450:5432'
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=dev_recipemanagement
volumes:
- recipemanagement-data:/var/lib/postgresql/data
recipemanagement-api:
build:
context: .
dockerfile: RecipeManagement/src/RecipeManagement/Dockerfile
ports:
- "52451:8080"
environment:
ASPNETCORE_ENVIRONMENT: "Development"
DB_CONNECTION_STRING: "Host=recipemanagement-db;Port=5432;Database=dev_recipemanagement;Username=postgres;Password=postgres"
volumes:
- ~/.aspnet/https:/https:ro
volumes:
recipemanagement-data: