I'm trying to create a Docker image for a .NET Core unit test project, so I can run unit tests in a Linux environment (since that's where my app is being deployed), rather than my Windows dev environment. The solution structure is like this:
MySolution
|
|--MyApp
|
|--MyLib
|
|--UnitTests
UnitTests
references MyApp
, and MyApp
references MyLib
. So I created a Dockerfile in my UnitTests
project:
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY UnitTests.csproj UnitTests/
COPY *.config UnitTests/
COPY appsettings.json UnitTests/
COPY ../MyApp/MyApp.csproj MyApp/
COPY ../MyLib/MyLib.csproj MyLib/
WORKDIR /src/UnitTests
RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build UnitTests.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish UnitTests.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["tail", "-f", "/dev/null"]
But when I try to build the image:
docker build --pull -t unittests .
It gets to the point when I try to copy over MyApp
and fails with
COPY failed: Forbidden path outside the build context: ../MyApp/MyApp.csproj ()
I can't put the Dockerfile in the root directory, because that applies to the solution; it's meant to be specifically for my unit tests. So how am I supposed to include the dependencies of my project in the Dockerfile?
One way to approach this is to put your Dockerfile
in the UnitTests directory, but invoke Docker from the parent directory specifying the path the dockerfile:
docker build --pull -t unittests --file UnitTest/Dockerfile .
You'll then need to adjust some paths in your dockerfile:
FROM microsoft/dotnet:2.1-sdk AS build
WORKDIR /src
COPY /UnitTests/UnitTests.csproj UnitTests/
COPY /UnitTests/*.config UnitTests/
COPY /UnitTests/appsettings.json UnitTests/
COPY /MyApp/MyApp.csproj MyApp/
COPY /MyLib/MyLib.csproj MyLib/
WORKDIR /src/UnitTests
RUN dotnet restore -nowarn:msb3202,nu1503
RUN dotnet build UnitTests.csproj -c Release -o /app
FROM build AS publish
RUN dotnet publish UnitTests.csproj -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["tail", "-f", "/dev/null"]
Another way to handle it would be to have multiple dockerfiles in the root directory:
Dockerfile <-- "Main" dockerfile for the build of the product
Dockerfile.UnitTests <!-- Unit test dockerfile
And yet another way to approach it would be to integrate the unit tests into your "main" Dockerfile. The advantage here is that your unit tests get automatically run whenever you build your main image - no separate build is necessary.
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