As a .NET developer, when you build a container image for your app, you can use the Dockerfile
to define the container image. However, you can also use the dotnet publish
command to build and publish the container image without a Dockerfile
. This repository provides sample .NET apps using container images with Dockerfile
and with dotnet publish
.
In addition to that, if you want to orchestrate containers Docker Compose is usually the first approach. However, you can also use the .NET Aspire to generate the Docker Compose file from the .NET Aspire manifest JSON file. This repository also provides a sample .NET app using the .NET Aspire to orchestrate containers.
- .NET SDK 8.0+ with .NET Aspire workload
- Visual Studio or Visual Studio Code + C# Dev Kit
- Aspirate
- Docker Desktop
-
Run
docker init
to create a new Dockerfile for web app.pushd ./MSBuildForContainers.WebApp docker init docker build . -t webapp:latest docker run -d -p 3000:8080 webapp:latest popd
-
Run
docker init
to create a new Dockerfile for API app.pushd ./MSBuildForContainers.ApiApp docker init docker build . -t apiapp:latest docker run -d -p 5050:8080 apiapp:latest popd
-
Open the browser and navigate to
http://localhost:3000
to see the web app running andhttp://localhost:5050
to see the API app running.
-
Run the following
dotnet publish
command to build and publish the web app.dotnet publish ./MSBuildForContainers.WebApp \ -t:PublishContainer \ --os linux --arch x64 docker run -d -p 3000:8080 webapp:latest
-
Run the following
dotnet publish
command to build and publish the web app.dotnet publish ./MSBuildForContainers.ApiApp \ -t:PublishContainer \ --os linux --arch x64 docker run -d -p 5050:8080 apiapp:latest
-
If you want to change the base image to Ubuntu Chiseled image, use the following command.
dotnet publish ./MSBuildForContainers.ApiApp \ -t:PublishContainer \ --os linux --arch x64 \ -p:ContainerBaseImage=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled \ -p:ContainerRepository=apiapp \ -p:ContainerImageTag=latest dotnet publish ./MSBuildForContainers.WebApp \ -t:PublishContainer \ --os linux --arch x64 \ -p:ContainerBaseImage=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled \ -p:ContainerRepository=webapp \ -p:ContainerImageTag=latest docker run -d -p 3000:8080 webapp:latest docker run -d -p 5050:8080 apiapp:latest
-
Check Docker Desktop to see the container image size and compare it from the previous step.
-
Open the browser and navigate to
http://localhost:3000
to see the web app running andhttp://localhost:5050
to see the API app running.
-
Update the web app to reference API app by commenting and uncommenting the
Program.cs
file in theMSBuildForContainers.WebApp
project. -
Run the following command to rebuild the container image.
dotnet publish ./MSBuildForContainers.WebApp \ -t:PublishContainer \ --os linux --arch x64 \ -p:ContainerBaseImage=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled \ -p:ContainerRepository=webapp \ -p:ContainerImageTag=latest
-
Run the following
docker compose
command to run both apps.docker compose -f ./docker-compose.yaml up
-
Open the browser and navigate to
http://localhost:3000
to see the web app running andhttp://localhost:5050
to see the API app running.
-
Switch to the
aspire
branch.git switch aspire
-
Run the following command to see whether the .NET Aspire dashboard is running
dotnet watch run --project ./MSBuildForContainers.AppHost
-
Generate .NET Aspire manifest JSON file.
dotnet run --project ./MSBuildForContainers.AppHost \ -- \ --publisher manifest \ --output-path ../aspire-manifest.json
-
Generate the Docker Compose file from the .NET Aspire manifest JSON file.
aspirate generate \ --project-path ./MSBuildForContainers.AppHost \ --aspire-manifest ./aspire-manifest.json \ --output-format compose \ --disable-secrets --include-dashboard false
-
Run the Docker Compose file generated by the .NET Aspire.
docker compose -f ./aspirate-output/docker-compose.yaml up
-
Open the browser and navigate to
http://localhost:10002
to see the web app running andhttp://localhost:10000
to see the API app running.