diff --git a/.github/linters/.check-markdown-links.json b/.github/linters/.check-markdown-links.json deleted file mode 100644 index c008fa8cf8..0000000000 --- a/.github/linters/.check-markdown-links.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "aliveStatusCodes": [200, 406], - "ignorePatterns": [ - { - "pattern": "^https://dev.azure.com/dnceng/internal/_build\\?definitionId=359" - }, - { - "pattern": "^https://github.com/dotnet/dotnet-docker/blob/\\{\\{if" - }, - { - "pattern": "^https://github.com/dotnet/release/blob/main/.github/ISSUE_TEMPLATE/dotnet-docker-servicing-release.md" - }, - { - "pattern": "^https://mcr.microsoft.com/v2/\\{\\{REPO\\}\\}/tags/list" - }, - { - "pattern": "^https://support.microsoft.com/contactus/" - }, - { - "pattern": "^l-is-the-package-in-the-linux-distro-base-image" - } - ], - "retry": - { - "count": 3, - "interval": "3000" - } -} diff --git a/.github/linters/.linkspector.yml b/.github/linters/.linkspector.yml new file mode 100644 index 0000000000..bde805e8b1 --- /dev/null +++ b/.github/linters/.linkspector.yml @@ -0,0 +1,12 @@ +aliveStatusCodes: + - 200 + - 406 +dirs: + - . + - .github +excludedDirs: + - eng/readme-templates +ignorePatterns: + - pattern: "^https://github.com/dotnet/release/blob/main/.github/ISSUE_TEMPLATE/dotnet-docker-servicing-release.md" + - pattern: "^l-is-the-package-in-the-linux-distro-base-image" +useGitIgnore: true diff --git a/.github/workflows/check-markdown-links.yml b/.github/workflows/check-markdown-links.yml index 225f3ed838..681caf354a 100644 --- a/.github/workflows/check-markdown-links.yml +++ b/.github/workflows/check-markdown-links.yml @@ -17,8 +17,8 @@ jobs: uses: actions/checkout@v4 - name: Check markdown links - uses: gaurav-nelson/github-action-markdown-link-check@v1 + uses: umbrelladocs/action-linkspector@v1 with: - config-file: .github/linters/.check-markdown-links.json - use-quiet-mode: 'yes' - use-verbose-mode: 'no' + config_file: .github/linters/.linkspector.yml + fail_on_error: true + filter_mode: nofilter diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8e2a2682e3..f6a09da4e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -71,11 +71,11 @@ The [`build-and-test.ps1`](https://github.com/dotnet/dotnet-docker/blob/main/bui #### Editing Dockerfiles -The [Dockerfiles](https://github.com/search?q=repo%3Adotnet%2Fdotnet-docker+filename%3ADockerfile&type=Code&ref=advsearch&l=&l=) contained in this repo are generated from a set of [Cottle](https://cottle.readthedocs.io/en/stable/page/01-overview.html) based [templates](https://github.com/dotnet/dotnet-docker/tree/main/eng/dockerfile-templates). A single template generates the set of Dockerfiles that are similar (e.g. all Windows sdk Dockerfiles for a particular .NET version). This ensures consistency across the various Dockerfiles and eases the burden of making changes to the Dockerfiles. Instead of editing the Dockerfiles directly, the templates should be updated and then the Dockerfiles should get regenerated by running the [generate Dockerfiles script](https://github.com/dotnet/dotnet-docker/blob/main/eng/dockerfile-templates/Get-GeneratedDockerfiles.ps1). +The [Dockerfiles](https://github.com/search?q=repo%3Adotnet%2Fdotnet-docker+path%3Asrc%2F**%2FDockerfile&type=code&ref=advsearch) contained in this repo are generated from a set of [Cottle](https://cottle.readthedocs.io/en/stable/page/01-overview.html) based [templates](https://github.com/dotnet/dotnet-docker/tree/main/eng/dockerfile-templates). A single template generates the set of Dockerfiles that are similar (e.g. all Windows sdk Dockerfiles for a particular .NET version). This ensures consistency across the various Dockerfiles and eases the burden of making changes to the Dockerfiles. Instead of editing the Dockerfiles directly, the templates should be updated and then the Dockerfiles should get regenerated by running the [generate Dockerfiles script](https://github.com/dotnet/dotnet-docker/blob/main/eng/dockerfile-templates/Get-GeneratedDockerfiles.ps1). #### Editing READMEs -The [READMEs](https://github.com/search?q=repo%3Adotnet%2Fdotnet-docker+filename%3AREADME+path%3A%2F&type=Code&ref=advsearch&l=&l=) contained in this repo are used as the descriptions for the Docker repositories the images are published to. Just like the Dockerfiles, the READMEs are generated from a set of [Cottle](https://cottle.readthedocs.io/en/stable/page/01-overview.html) based [templates](https://github.com/dotnet/dotnet-docker/tree/main/eng/readme-templates). This ensures consistency across the various READMEs and eases the burden of making changes. Instead of editing the READMEs directly, the templates should be updated and then the READMEs should get regenerated by running the [generate READMEs script](https://github.com/dotnet/dotnet-docker/blob/main/eng/readme-templates/Get-GeneratedReadmes.ps1). +The [READMEs](https://github.com/search?q=repo%3Adotnet%2Fdotnet-docker+path%3A**%2FREADME*+-path%3Aeng+-path%3Asamples&type=code&ref=advsearch&p=1) contained in this repo are used as the descriptions for the Docker repositories the images are published to. Just like the Dockerfiles, the READMEs are generated from a set of [Cottle](https://cottle.readthedocs.io/en/stable/page/01-overview.html) based [templates](https://github.com/dotnet/dotnet-docker/tree/main/eng/readme-templates). This ensures consistency across the various READMEs and eases the burden of making changes. Instead of editing the READMEs directly, the templates should be updated and then the READMEs should get regenerated by running the [generate READMEs script](https://github.com/dotnet/dotnet-docker/blob/main/eng/readme-templates/Get-GeneratedReadmes.ps1). #### Tests diff --git a/documentation/supported-tags.md b/documentation/supported-tags.md index 9b749462f8..9df97b850c 100644 --- a/documentation/supported-tags.md +++ b/documentation/supported-tags.md @@ -9,6 +9,7 @@ Complete tag lists: - [aspnet](../README.aspnet.md#full-tag-listing) - [sdk](../README.sdk.md#full-tag-listing) - [monitor](../README.monitor.md#full-tag-listing) +- [monitor-base](../README.monitor-base.md#full-tag-listing) - [aspire-dashboard](../README.aspire-dashboard.md#full-tag-listing) - [samples](../README.samples.md#full-tag-listing) - [Microsoft Artifact Registry](https://mcr.microsoft.com/en-us/catalog?search=dotnet/) diff --git a/documentation/vulnerability-reporting.md b/documentation/vulnerability-reporting.md index 7602b34ef8..f487ef103e 100644 --- a/documentation/vulnerability-reporting.md +++ b/documentation/vulnerability-reporting.md @@ -120,7 +120,19 @@ Rerun the scan of your image using your scanning tool. Ensure you get the latest When .NET drops support for an image tag, it means it will no longer be updated, even when there is a new base OS image available. This means that vulnerabilities will be reported for that image over time if it continues to be used. Our [supported tag policy](supported-tags.md) provides detailed information about when these tags are no longer supported. -The simple rule to follow: only the tags shown in our [tag listing](supported-tags.md#tag-listing) are supported. +The simple rule to follow: only the tags shown in our tag listing are supported: + +Complete tag lists: + +* [runtime-deps](../README.runtime-deps.md#full-tag-listing) +* [runtime](../README.runtime.md#full-tag-listing) +* [aspnet](../README.aspnet.md#full-tag-listing) +* [sdk](../README.sdk.md#full-tag-listing) +* [monitor](../README.monitor.md#full-tag-listing) +* [monitor-base](../README.monitor-base.md#full-tag-listing) +* [aspire-dashboard](../README.aspire-dashboard.md#full-tag-listing) +* [samples](../README.samples.md#full-tag-listing) +* [Microsoft Artifact Registry](https://mcr.microsoft.com/en-us/catalog?search=dotnet/) This script can be used to determine if the .NET image tag is supported: diff --git a/samples/build-in-sdk-container.md b/samples/build-in-sdk-container.md index 1f5f28e548..d5bf6759bc 100644 --- a/samples/build-in-sdk-container.md +++ b/samples/build-in-sdk-container.md @@ -1,27 +1,84 @@ # Build in a .NET SDK container -You can use Docker to run your build in an isolated environment using the [.NET SDK Docker image](../README.sdk.md). This is useful to either avoid the need to install .NET on the build machine or ensure that your environment is correctly configured (dev, staging, or production). +You can use Docker to run your build in an isolated environment using the [.NET SDK Docker image](../README.sdk.md). +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). -The 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. +## Build using a Dockerfile (Requires buildx) -## Requirements +Docker [buildx](https://docs.docker.com/reference/cli/docker/buildx/) has built-in support for [exporting files from the docker build command](https://docs.docker.com/build/building/export/). +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](./dotnetapp/Dockerfile.sdk-build) 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 ` 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: + +```pwsh +docker build --pull -f Dockerfile.sdk-build --output ./out . +``` + +You can also give it a try without cloning this repository: + +```pwsh +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](./build-for-a-platform.md). + +```pwsh +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: + +```pwsh +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](https://docs.docker.com/engine/admin/volumes/volumes/) (that's the `-v` argument) to make source available within the container (to build it). You may need to enable [shared drives (Windows)](https://docs.docker.com/docker-for-windows/#shared-drives) or [file sharing (macOS)](https://docs.docker.com/docker-for-mac/#file-sharing) 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](https://docs.microsoft.com/en-us/dotnet/core/rid-catalog) (`-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 +### 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: ```console -docker pull mcr.microsoft.com/dotnet/sdk:8.0 +docker pull mcr.microsoft.com/dotnet/sdk:9.0 ``` -## Linux +### Linux ```console -docker run --rm -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:8.0 dotnet publish -c Release -o out +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: @@ -31,10 +88,10 @@ $ ls out dotnetapp dotnetapp.deps.json dotnetapp.dll dotnetapp.pdb dotnetapp.runtimeconfig.json ``` -## macOS +### macOS ```console -docker run --rm -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:8.0 dotnet publish -c Release -o out -r osx-x64 --self-contained false +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: @@ -46,12 +103,12 @@ dotnetapp.deps.json dotnetapp.runtimeconfig.json dotnetapp.dll ``` -## Windows using Linux containers +### Windows using Linux containers The following example uses PowerShell. ```console -docker run --rm -v ${pwd}:/app -w /app mcr.microsoft.com/dotnet/sdk:8.0 dotnet publish -c Release -o out -r win-x64 --self-contained false +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: @@ -71,12 +128,12 @@ Mode LastWriteTime Length Name -a---- 11/2/2020 10:46 AM 152 dotnetapp.runtimeconfig.json ``` -## Windows using Windows containers +### Windows using Windows containers The following example uses PowerShell. ```console -docker run --rm -v ${pwd}:c:\app -w c:\app mcr.microsoft.com/dotnet/sdk:8.0-nanoserver-ltsc2022 dotnet publish -c Release -o out +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] @@ -100,14 +157,14 @@ Mode LastWriteTime Length Name -a---- 11/2/2020 10:49 AM 160 dotnetapp.runtimeconfig.json ``` -## Building to a separate location +### 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: ```console -docker run --rm -v ~/dotnetapp:/out -v $(pwd):/app -w /app mcr.microsoft.com/dotnet/sdk:8.0 dotnet publish -c Release -o /out -r osx-x64 --self-contained false +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: @@ -123,7 +180,7 @@ The following PowerShell example demonstrates doing that on Windows (using Linux ```console mkdir C:\dotnetapp -docker run --rm -v C:\dotnetapp:c:\app\out -v ${pwd}:c:\app -w /app mcr.microsoft.com/dotnet/sdk:8.0 dotnet publish -c Release -o out -r win-x64 --self-contained false +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: diff --git a/samples/dotnetapp/Dockerfile.sdk-build b/samples/dotnetapp/Dockerfile.sdk-build new file mode 100644 index 0000000000..b4c71e7866 --- /dev/null +++ b/samples/dotnetapp/Dockerfile.sdk-build @@ -0,0 +1,18 @@ +# Learn about building .NET container images: +# https://github.com/dotnet/dotnet-docker/blob/main/samples/README.md +FROM --platform=$BUILDPLATFORM mcr.microsoft.com/dotnet/sdk:9.0 AS build +ARG TARGETARCH +WORKDIR /source + +# Copy project file and restore as distinct layers +COPY --link *.csproj . +RUN dotnet restore -a $TARGETARCH + +# Copy source code and publish app +COPY --link . . +RUN dotnet publish -a $TARGETARCH --no-restore -o /out + +# Output stage +# Learn more about exporting binaries with Docker: https://docs.docker.com/build/building/export/ +FROM scratch +COPY --link --from=build /out .