Using CBL-Mariner 2.0 for ASP.NET Core Apps

Introduction

When CBL-Mariner 2.0 was announced, I wanted to try using its container images to run ASP.NET Core web apps.

As others have already blogged, we want to be sure to use a Docker multi-stage build with the runtime-deps image in order to reduce the size of the final image. At first I considered following this example to build a slimmed-down image based on CBL-Mariner’s distroless/minimal image, but then I discovered Microsoft has a Dockerfile to build the runtime-deps image for CBL-Mariner 2.0. It’s not documented, and very likely not supported, but you can pull it from Docker Hub as mcr.microsoft.com/dotnet/runtime-deps:6.0-cbl-mariner2.0.

I decided to go even further and use the distroless image. Not only will it be smaller, it should be more secure due to reducing unnecessary files in the image, and running your application as non-root.

Multi-Stage Dockerfile

Here’s a working Dockerfile that builds an ASP.NET Core web app container image based on cbl-mariner2.0-distroless:

# build the application using CBL-Mariner 2.0
FROM mcr.microsoft.com/dotnet/sdk:6.0-cbl-mariner2.0 AS build

# copy in the project file and restore dependencies
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore --runtime linux-x64

# copy in all source files
COPY . ./

# publish a trimmed application
RUN dotnet publish --no-restore -c Release -o out --runtime linux-x64 --self-contained true -p:PublishTrimmed=true -p:PublishSingleFile=true -p:LinkMode=trim

# run the application on a 'distroless' image
FROM mcr.microsoft.com/dotnet/runtime-deps:6.0-cbl-mariner2.0-distroless AS runtime

# copy in the built application
WORKDIR /app
COPY --from=build /app/out ./

# use a non-privileged port; https://github.com/dotnet/dotnet-docker/issues/3796
ENV ASPNETCORE_URLS=http://+:8080

# change the entrypoint name to match your web application
ENTRYPOINT ["./MyWebApp"]

Posted by Bradley Grainger on May 26, 2022