Skip to content

Latest commit

 

History

History
206 lines (144 loc) · 8.41 KB

build-in-sdk-container.md

File metadata and controls

206 lines (144 loc) · 8.41 KB

Build in a .NET SDK container

You can use Docker to run your build in an isolated environment using the .NET SDK Docker image. This is useful to avoid the need to install .NET on the build machine and helps ensure that your build environment is correctly configured (dev, staging, or production).

Build using a Dockerfile (Requires buildx)

Docker buildx has built-in support for exporting files from the docker build command. Using a Dockerfile to build .NET apps is advantageous because it allows you to specify all of the apps required dependencies and build instructions in one place.

The dotnetapp sample contains a sample Dockerfile that supports this functionality. This sample uses a multi-stage Dockerfile with a FROM scratch stage. The Dockerfile copies the build outputs into that stage using the COPY instruction. Then, when you provide the --output/-o <directory> argument to the Docker build command, Docker will copy the entire filesystem of the final stage of the image to the specified directory. Since the sample Dockerfile's final stage is a FROM scratch stage, the result is that the build outputs are placed in the specified directory on the host machine's disk.

Build single-platform binary

From the samples/dotnetapp directory:

docker build --pull -f Dockerfile.sdk-build --output ./out .

You can also give it a try without cloning this repository:

docker build --pull -f Dockerfile.sdk-build --output ./out 'https://github.com/dotnet/dotnet-docker.git#:samples/dotnetapp'

Build binaries for multiple platforms at once

Taking advantage of Docker buildx, you can cross-build binaries for multiple platforms at once, all without using emulation. For more info about how this works, see our documentation on building images for a specific platform.

docker buildx build --pull --platform linux/amd64,linux/arm64 -f ./samples/dotnetapp/Dockerfile.sdk-build --output out ./samples/dotnetapp/

Docker buildx will create a separate sub-directory for each target platform:

PS> tree /F out
C:\...\dotnetapp\out
├───linux_amd64
│       dotnetapp
│       dotnetapp.deps.json
│       dotnetapp.dll
│       dotnetapp.pdb
│       dotnetapp.runtimeconfig.json
└───linux_arm64
        dotnetapp
        dotnetapp.deps.json
        dotnetapp.dll
        dotnetapp.pdb
        dotnetapp.runtimeconfig.json

Build by running Docker container directly

If you can't use Docker buildx or don't want to use a Dockerfile, you can build your app by running the SDK image directly and volume mounting your app's source code into the container. These instructions assume that you have cloned the repository locally, and that you are in the samples/dotnetapp directory (due to the volume mounting syntax), as demonstrated by the examples.

Requirements

This scenario relies on volume mounting (that's the -v argument) to make source available within the container (to build it). You may need to enable shared drives (Windows) or file sharing (macOS) first.

dotnet publish (and build) produces native executables for applications. If you use a Linux container, you will build a Linux executable that will not run on Windows or macOS. You can use a runtime argument (-r) to specify the type of assets that you want to publish (if they don't match the SDK container). The following examples assume you want assets that match your host operating system, and use runtime arguments to ensure that.

Pull SDK image

It is recommended to pull the SDK image before running the appropriate command. This ensures that you get the latest patch version of the SDK. Use the following command:

docker pull mcr.microsoft.com/dotnet/sdk:9.0

Linux

docker run --rm -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:9.0 dotnet publish -c Release -o out

You can see the built binaries with the following command:

$ ls out
dotnetapp  dotnetapp.deps.json  dotnetapp.dll  dotnetapp.pdb  dotnetapp.runtimeconfig.json

macOS

docker run --rm -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:9.0 dotnet publish -c Release -o out -r osx-x64 --self-contained false

You can see the built binaries with the following command:

% ls out
dotnetapp                       dotnetapp.pdb
dotnetapp.deps.json             dotnetapp.runtimeconfig.json
dotnetapp.dll

Windows using Linux containers

The following example uses PowerShell.

docker run --rm -v ${pwd}:/app -w /app mcr.microsoft.com/dotnet/sdk:9.0 dotnet publish -c Release -o out -r win-x64 --self-contained false

You can see the built binaries with the following command:

PS C:\git\dotnet-docker\samples\dotnetapp> dir out


    Directory: C:\git\dotnet-docker\samples\dotnetapp\out

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         11/2/2020  10:46 AM            449 dotnetapp.deps.json
-a----         11/2/2020  10:46 AM           7680 dotnetapp.dll
-a----         11/2/2020  10:46 AM         141312 dotnetapp.exe
-a----         11/2/2020  10:46 AM           9444 dotnetapp.pdb
-a----         11/2/2020  10:46 AM            152 dotnetapp.runtimeconfig.json

Windows using Windows containers

The following example uses PowerShell.

docker run --rm -v ${pwd}:c:\app -w c:\app mcr.microsoft.com/dotnet/sdk:9.0-nanoserver-ltsc2022 dotnet publish -c Release -o out

Warning

From .NET 8 onwards, .NET multi-platform images are Linux-only. This means Windows containers must all be referenced by a full tag name including the specific Windows version.

You can see the built binaries with the following command:

PS C:\git\dotnet-docker\samples\dotnetapp> dir out


    Directory: C:\git\dotnet-docker\samples\dotnetapp\out

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         11/2/2020  10:49 AM            419 dotnetapp.deps.json
-a----         11/2/2020  10:49 AM           8192 dotnetapp.dll
-a----         11/2/2020  10:49 AM         141312 dotnetapp.exe
-a----         11/2/2020  10:49 AM           9440 dotnetapp.pdb
-a----         11/2/2020  10:49 AM            160 dotnetapp.runtimeconfig.json

Building to a separate location

You may want the build output to be written to a separate location than the source directory. That's easy to do with a second volume mount.

The following example demonstrates doing that on macOS:

docker run --rm -v ~/dotnetapp:/out -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:9.0 dotnet publish -c Release -o /out -r osx-x64 --self-contained false

You can see the built binaries with the following command:

> ls ~/dotnetapp
dotnetapp                       dotnetapp.pdb
dotnetapp.deps.json             dotnetapp.runtimeconfig.json
dotnetapp.dll

The following PowerShell example demonstrates doing that on Windows (using Linux containers):

mkdir C:\dotnetapp
docker run --rm -v C:\dotnetapp:c:\app\out -v ${pwd}:c:\app -w /app mcr.microsoft.com/dotnet/sdk:9.0 dotnet publish -c Release -o out -r win-x64 --self-contained false

You can see the built binaries with the following command:

PS C:\git\dotnet-docker\samples\dotnetapp> dir C:\dotnetapp\


    Directory: C:\dotnetapp

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----         11/2/2020  10:52 AM            472 dotnetapp.deps.json
-a----         11/2/2020  10:52 AM           7680 dotnetapp.dll
-a----         11/2/2020  10:52 AM         141312 dotnetapp.exe
-a----         11/2/2020  10:52 AM           9452 dotnetapp.pdb
-a----         11/2/2020  10:52 AM            160 dotnetapp.runtimeconfig.json

More Samples