Skip to content

Repository files navigation

Build Nightly Scan Auto Update Quality Gate Status Bugs Code Smells Duplicated Lines (%)

Docker .NET

This repository contains .NET parent Docker image source code for Defra.

The following table lists the versions of .NET available, and the parent image they are based on:

.NET version SDK version Runtime version Parent image
8.0 8.0.424 8.0.30 8.0-alpine3.24
10.0 10.0.400 10.0.11 10.0-alpine3.24

Two parent images are created from this repository:

  • defra-dotnetcore
  • defra-dotnetcore-development

It is recommended that services use multi-stage builds to produce production and development images, each extending the appropriate parent, from a single Dockerfile.

The development image is based on the .NET SDK, whilst the production image is based on the .NET Runtime (including ASP.NET).

Example file

An example is provided to show how parent images can be extended for different types of services. These should be a good starting point for building .NET services conforming to Defra standards.

example/Dockerfile - This is an example project that consumes the parent images created by this repository.

Supported .NET versions

Services should use the latest LTS version of .NET.

As such, the maintained parent images will align to the versions of LTS still receiving security updates.

Internal CA certificates

The image includes the certificate for the internal CA so that traffic can traverse the network without encountering issues.

Versioning

Images should be tagged according to the Dockerfile version and the version of .NET on which the image is based. For example, for Dockerfile version 1.0.0 based on .NET 8.0, the built image would be tagged 1.0.0-dotnetcore8.0.

CI/CD

On commit GitHub Actions will build both dotnetcore and dotnetcore-development images for the .NET versions listed in the image-matrix.json file, and perform a vulnerability scan, as described below.

In addition a commit to the main branch will push the images to the defradigital organisation in Docker Hub using the version tag specified in the JOB.env file. This tag is bumped automatically by the auto-update workflow (see below).

The .NET version marked as latest in the image-matrix.json will be tagged as the latest image in Docker Hub.

Image vulnerability scanning

A GitHub Action runs a nightly scan of the images published to Docker Hub using Anchore Grype and Aqua Trivy, and every push to a branch scans the image before it can be released.

A build is only blocked by vulnerabilities that have a fix available, so unpatchable findings do not stop delivery. The nightly scan records every finding, fixable and unfixable, in a single tracking issue labelled security-scan.

For more details see Image Scanning

Software Bill of Materials (SBOM)

On every push to main, each production image variant has an SBOM generated from its actual container contents using Syft (via anchore/sbom-action), which is:

  • submitted to this repository's Dependency graph, so vulnerable OS packages and runtime dependencies show up alongside Dependabot alerts, and
  • uploaded as a downloadable workflow artifact for that run.

The image pushed to Docker Hub also carries the same SBOM as a build attestation (docker buildx build --sbom=true). You can inspect it directly from the published image without pulling it:

docker buildx imagetools inspect defradigital/dotnetcore:<tag> --format '{{json (index .SBOM "linux/amd64").SPDX}}'

Retiring a version

Each supported .NET version submits its SBOM to the Dependency Graph under its own correlator (docker-image-dotnet-<version>), and GitHub only ever shows the latest submission for a given correlator. So if a version is simply deleted from image-matrix.json once it drops out of LTS, nothing ever submits again for that correlator, and the Dependency Graph (and any Dependabot alerts derived from it) would keep showing that version's packages forever, frozen at whatever they were on its last build.

To retire a version cleanly, run scripts/retire-version.sh with the .NET version, e.g. ./scripts/retire-version.sh 8.0. It removes the version from image-matrix.json and the table above, and submits an empty snapshot for that version's correlator to clear it from the Dependency Graph. Review the resulting diff, then commit it and open a PR as normal. Requires jq and an authenticated gh CLI.

Automated version updates

The auto-update workflow runs nightly. It checks the .NET release metadata for new SDK and runtime releases on each supported channel, and when it finds one it opens a pull request that bumps the affected versions across the image-matrix.json, JOB.env, Dockerfile, README.md and the example.

Because unfixable vulnerabilities no longer block a build (see Image Scanning), these pull requests normally pass the scan on their own. Once a reviewer approves, the PR merges automatically and the new images are published.

Repository setup

The automation relies on a few repository settings:

  • Branch protection on main: add required-check (from the build-scan-push workflow) as a required status check. It is a single, stable check that passes only when every image in the matrix has built and scanned cleanly, so it stays valid across version bumps. The individual matrix jobs are named per version and cannot be pinned directly.
  • Allow auto-merge: enable it under Settings → General → Pull Requests so update PRs can merge once approved and green.
  • Pull request review: keep review required. Update PRs still need a single human approval; the required-check gate is the security backstop.
  • security-scan label: create it once. The nightly scan uses it to find and update its single tracking issue.
  • Secrets and variables: DOCKER_USERNAME, DOCKER_TOKEN, APP_ID, APP_PRIVATE_KEY and the PR_REVIEW_TEAM variable are already configured and used by the workflows.

Building images locally

To build the images locally, run:

docker build --no-cache --target <target> .

(where is either development or production).

This will build an image using the default BASE_VERSION as set in the Dockerfile.

Licence

THIS INFORMATION IS LICENSED UNDER THE CONDITIONS OF THE OPEN GOVERNMENT LICENCE found at:

http://www.nationalarchives.gov.uk/doc/open-government-licence/version/3

The following attribution statement MUST be cited in your products and applications when using this information.

Contains public sector information licensed under the Open Government license v3

About the licence

The Open Government Licence (OGL) v3.0 was developed by the The National Archives to enable information providers in the public sector to license the use and re-use of their information under a common open licence.

It is designed to encourage use and re-use of information freely and flexibly, with only a few conditions.

About

.NET Docker parent image

Resources

Security policy

Stars

0 stars

Watchers

2 watching

Forks

Releases

Packages

Used by

Contributors

Languages