You no longer need a Dockerfile

You no longer need a Dockerfile

You no longer need a Dockerfile

The .Net 7 release is bringing a lot of changes, and one of the most significant is the removal of the need for a Dockerfile. Container images are now a supported output type of the .NET SDK.

You no longer need a separate Dockerfile to containerize your .NET applications. You can publish your application and it will be built into a container image.

This is a significant improvement for .NET developers who want to containerize their applications. It will make it much easier to distribute and run your applications in the cloud. In this article, we’ll take a look at what this change means for you and your applications.

Stay in touch

Subscribe to our mailing list to stay updated on topics and videos related to .NET, Azure, and DevOps!

Previously in Dockerfile

Create a new Web API project, and open the project in Visual Studio. In the solution explorer, right-click on the project and select Add Docker Support. This will enable the addition of Docker functionality to the pre-existing project

I’m using Visual Studio for Mac, Windows has the same functionality

The following Dockerfile was generated by Visual Studio when docker support was added. It provides a helpful starting point for configuring your application’s Docker environment. You can customize the contents of this file as needed to fit your application’s requirements. Take a look at what’s included below:


FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443

FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["ApiWithDockerfile/ApiWithDockerfile.csproj", "ApiWithDockerfile/"]
RUN dotnet restore "ApiWithDockerfile/ApiWithDockerfile.csproj"
COPY . .
WORKDIR "/src/ApiWithDockerfile"
RUN dotnet build "ApiWithDockerfile.csproj" -c Release -o /app/build

FROM build AS publish
RUN dotnet publish "ApiWithDockerfile.csproj" -c Release -o /app/publish /p:UseAppHost=false

FROM base AS final
WORKDIR /app
COPY --from=publish /app/publish .
ENTRYPOINT ["dotnet", "ApiWithDockerfile.dll"]

Visual Studio will detect the type of project (aspnet) and its version (7.0), download the runtime to run the application, download the SDK for building the application, and execute necessary COPY and dotnet restore commands associated with the project’s csproj.

If we want to build and run the project in docker, Visual Studio is an option. For those who prefer the command line, we can run this command from the solution root level

docker build -f ApiWithDockerfile/Dockerfile -t apiwithdockerfile:0.1 .

The following command will enable you to run the project in a local docker environment:

docker run -p 5000:80 apiwithdockerfile:0.1

You can now call the weather API http://localhost:5000/WeatherForcast and should receive a normal response without any issues. That’s all there is to it.

The Annoying part

It can be quite difficult to maintain multiple projects while working with Dockerfiles. You need to be sure that all of the paths, variables, and ports are accurate in order for your Dockerfile to build and run as expected. Even seemingly small errors can lead to big headaches down the line. This task may quickly become overwhelming if you have several projects going within your Dockerfile.

The new part in .Net 7

In .Net 7, Microsoft made it easier than ever to deploy your apps to containers using their new Nuget package, Microsoft.NET.Build.Containers! It allows your project to be self-aware of its ability to be deployed in a container, and after adding the Nuget package you can simply publish the application by using the dotnet publish command in your project’s root folder – no need for a Dockerfile!

dotnet publish -os linux --arch x64 -p:PublishProfile=DefaultContainer

This will publish a new docker image with a tag/version 1.0.0 and the name of the image is the same name as the project.

Now you can use the same docker run command to launch your newly built image with a default tag of 1.0.0

docker run -p 5000:80 apiwithdockerfile:1.0.0

Using csproj properties

I think I know what your next question is – how do you run DevOps pipelines without manually adding all the variables into each publish command? The solution lies in the csproj file. Check out this example

<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <Nullable>enable</Nullable>
    <ImplicitUsings>enable</ImplicitUsings>

    <PublishProfile>DefaultContainer</PublishProfile>
    <ContainerBaseImage>mcr.microsoft.com/dotnet/aspnet:7.0</ContainerBaseImage>
    <ContainerRegistry>myregistry.com:1234</ContainerRegistry>
    <ContainerImageTag>1.0.1-patch2</ContainerImageTag>
    

  </PropertyGroup>

  <ItemGroup>
      <ContainerPort Include="80" Type="tcp" />
      <ContainerEnvironmentVariable Include="MyVariable" Value="MyValue" />
  </ItemGroup>

  <PropertyGroup Condition=" '$(RunConfiguration)' == 'https' " />
  <PropertyGroup Condition=" '$(RunConfiguration)' == 'http' " />
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="7.0.0" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
    <PackageReference Include="Microsoft.NET.Build.Containers" Version="0.2.7" />
  </ItemGroup>

</Project>

ContainerBaseImage: It’s possible to change the base image detected from the project to use a different runtime if it better fits your needs. Overriding the default base image provides more flexibility in terms of usage.

ContainerRegistry If you intend to upload your image to a cloud registry

At the moment of writing, authentication for a cloud registry isn’t supported yet.

ContainerImageTag Save the image tag, and if you need to specify multiple tags, you can use ContainerImageTags and provide a comma-separated list. For environment variables, use the ContainerEnvironmentVariable parameter, and specifying ports can be done with ContainerPort.

Conclusion

In conclusion, you no longer need a Dockerfile. This is good news because it means that you can spend less time managing your Dockerfiles and more time focusing on your application. This article showed you how to use the new package Microsoft.NET.Build.Containers and how to publish your .Net application into a docker container.

You can check the source code here in my github repository https://github.com/mhdbouk/NoDockerFileSupport/

Happy coding and catch you in the next one 👋

Recent Posts

Azure-Sync: Sync your Azure App Settings to local
Azure-Sync is a handy shell script tool designed to help .NET developers working with Azure App Services. Inspired by the functionality provided by the Azure …
Implement Builders easily with Source Generator in .NET
I created a YouTube video on Source Generator in which I showcased one possible implementation. However, I feel that I didn’t fully highlight its capabilities. …
Secure On-Premise .NET Application with Azure Key Vault
Suppose you have your Web App and Database server hosted locally on your On-Premises servers. You want to use Azure Key Vault with your .NET …
Running Integration Tests with Docker in .NET using TestContainers
Hello everyone, in today's post I will show you the easiest and cleanest way to perform integration testing of your code with database dependencies with …

2 thoughts on “You no longer need a Dockerfile

Leave a Reply

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.