Safeguard
Application Security•

How do you containerize a .NET application safely?

Use a multi-stage Dockerfile, a small runtime image, a non-root user and pinned versions. A practical checklist for packaging a .NET app as a container.

Safeguard Security Team
4 min read

To containerize a .NET application safely, build it in one image stage and ship only the published output in a smaller runtime image. Pin base image versions, run as a non-root user, keep secrets out of the image, and scan both the image and the app dependencies before every release.

What does Microsoft's own guidance start with?

The official tutorial walks through four steps: create and publish a simple .NET app, write a Dockerfile, build the image, and run the container. It lists the benefits of containers as immutable infrastructure, a portable architecture and scalability. It also points out two details people miss. ASP.NET Core apps have their own separate tutorial, and you can publish a .NET app as a container without Docker or Podman using the dotnet publish route.

So there is more than one way to produce the image. Pick one and make it the only way your pipeline does it, so that every release is built the same.

Why use a multi-stage build?

The .NET SDK includes compilers and tools you need at build time and do not want in production. A multi-stage Dockerfile uses an SDK image to restore and publish, then copies only the published folder into a runtime image. The result is smaller and has fewer packages for a scanner to flag, and fewer for an attacker to use.

Order your Dockerfile so that the project file and restore step come before the source copy. That keeps restore cached when only code changes, which makes builds quick enough that nobody is tempted to skip them.

What should you pin and what should you not bake in?

Pin the base image to a specific version tag, and ideally a digest, so a rebuild next month does not silently change the operating system under you. Then schedule a rebuild on a regular basis so you pick up base image fixes on purpose.

Do not copy secrets into the image. Anything written into a layer can be read by anyone who pulls the image, even if a later layer deletes the file. Pass credentials at run time through your orchestrator's secret mechanism.

Run the process as a non-root user. Check the documentation for the specific base image you use to see which user it provides, since this has changed across versions.

A constructed example

A team has a worker service that processes invoices. Its first Dockerfile used the SDK image for everything, ran as root, and copied an appsettings file containing a database password. Three fixes made it better. They moved to two stages. They changed the runtime stage to a non-root user. They deleted the password from the file and read it from an environment variable injected at run time. The image shrank, the scanner report got shorter, and a leaked image no longer meant a leaked database.

How to check or apply this

  1. Decide on one build route (Dockerfile or dotnet publish container support) and use it in CI only.
  2. Use two stages: SDK to build, runtime to run.
  3. Pin base image versions and rebuild on a schedule.
  4. Run as a non-root user and drop anything the app does not need.
  5. Search the image history for secrets, and move them to run-time injection.
  6. Scan the image and the NuGet dependency tree before release, and fail the build on findings you have agreed to block.

Safeguard scans dependency trees and can gate a pull request or pipeline on policy, which fits step 6. Image layer scanning is a separate job, so check what your current scanner covers.

Quick check

Does a smaller image mean a more secure image?

Usually it means fewer things to patch and exploit, but it is not a guarantee. You still need to scan and to manage the app's own dependencies.

Can I deploy ASP.NET Core with the same tutorial?

Microsoft notes that its console app tutorial is not for ASP.NET Core and links a separate tutorial for it. The security habits above apply to both.

Sources

Last reviewed: 18 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.