Skip to main content
Source Link
Dave New
  • 235
  • 2
  • 8

Dockerfile to generate a unit test image AND a production image

I use a single dockerfile to build and run the following images:

Production application image:

docker build -t myapplication.program -f src/MyApplication.Program/dockerfile  --target runner --build-arg version=1.0.19031.1 .

docker run --rm -it -e ASPNETCORE_ENVIRONMENT=local -p 5050:5050 myapplication.program:latest

Unit test and code coverage image:

docker build -t myapplication.tests -f src/MyApplication.Program/dockerfile --target tester .

docker run --rm -it -v $PWD/codecoveragereports:/app/test/MyApplication.UnitTests/codecoveragereports myapplication.tests:latest

Dockerfile:

# Define the base image with .NET Core SDK to enable restoring, building & publishing the code.
FROM microsoft/dotnet:2.1-sdk AS builder
# Set working directory in the container to /app. All further actions to affect this directory.
WORKDIR /app
# Copy csproj files from the source (period indicating the root solution directory) to our image (period indicating working directory).
COPY ./src/MyApplication.Program/MyApplication.Program.csproj ./src/MyApplication.Program/MyApplication.Program.csproj
COPY ./src/MyApplication.Interfaces/MyApplication.Interfaces.csproj ./src/MyApplication.Interfaces/MyApplication.Interfaces.csproj
COPY ./src/MyApplication.SignalR/MyApplication.SignalR.csproj ./src/MyApplication.SignalR/MyApplication.SignalR.csproj
COPY ./src/MyApplication.Protocol/MyApplication.Protocol.csproj ./src/MyApplication.Protocol/MyApplication.Protocol.csproj
COPY ./src/MyApplication.Domain/MyApplication.Domain.csproj ./src/MyApplication.Domain/MyApplication.Domain.csproj
COPY ./src/MyApplication.Infrastructure/MyApplication.Infrastructure.csproj ./src/MyApplication.Infrastructure/MyApplication.Infrastructure.csproj
COPY ./src/MyApplication.Services/MyApplication.Services.csproj ./src/MyApplication.Services/MyApplication.Services.csproj
COPY ./src/MyApplication.Actors/MyApplication.Actors.csproj ./src/MyApplication.Actors/MyApplication.Actors.csproj
# Copy nuget.config to root working directory - dotnet restore will use this.
COPY nuget.config ./
# Set working directory to starting project folder.
WORKDIR ./src/MyApplication.Program/
# Run dotnet package restore on all projects.
RUN dotnet restore
# Reset working directory back to /app
WORKDIR /app
# Copy all source code to image.
COPY ./src ./src
# Set working directory to starting project folder.
WORKDIR ./src/MyApplication.Program/
# Build the main project
RUN dotnet build MyApplication.Program.csproj -c Release

FROM builder as tester
# Set working directory in the container to /app. All further actions to affect this directory.
WORKDIR /app
# Copy csproj files from the source (period indicating the root solution directory) to our image (period indicating working directory).
COPY ./test/MyApplication.UnitTests/MyApplication.UnitTests.csproj ./test/MyApplication.UnitTests/MyApplication.UnitTests.csproj
# Set working directory to starting project folder.
WORKDIR ./test/MyApplication.UnitTests/
# Run dotnet package restore on all projects.
RUN dotnet restore
# Reset working directory back to /app
WORKDIR /app
# Copy all source code to image.
COPY ./test ./test
# Set working directory to starting project folder.
WORKDIR ./test/MyApplication.UnitTests/
# Build the main project
RUN dotnet test /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura
# Entry point command to generate the reports
ENTRYPOINT ["dotnet", "reportgenerator", "-reports:coverage.cobertura.xml", "-targetdir:codecoveragereports", "-reportTypes:htmlInline"]

FROM builder as publisher
# Reset working directory back to /app
WORKDIR /app
# Set working directory to starting project folder.
WORKDIR ./src/MyApplication.Program/
# Expect an argument for the artefact version number.
ARG version
# Dotnet publish project.
RUN dotnet publish MyApplication.Program.csproj -c Release -o publish /p:Version=$version

# Define the base image with just the (lightweight) .NET Core runtime to host and run MyApplication.
FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runner
# Set working directory in the container to /app. All further actions to affect this directory.
WORKDIR /app
# Copy published output from the builder image.
COPY --from=publisher /app/src/MyApplication.Program/publish/ .
# Listen on this port at runtime.
EXPOSE 5050
# Set application entry point
ENTRYPOINT ["dotnet", "MyApplication.Program.dll"]

Please code review my dockerfile.