Go to file
Mathias Beaulieu-Duncan 7cf9b1b914
Some checks failed
Build and Push .NET Images / discover (release) Successful in 2s
Build and Push .NET Images / build (release) Failing after 9m32s
Install apko as binary instead of running via Docker
The Gitea runner executes inside Docker, so volume mounts from
docker run resolve against the host filesystem where the workspace
path does not exist. Install apko directly on the runner to avoid
the Docker-in-Docker volume mount issue.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-03 17:39:57 -05:00
.gitea/workflows Install apko as binary instead of running via Docker 2026-02-03 17:39:57 -05:00
apko Fix registry secret names and add busybox to SDK 2026-02-03 16:45:18 -05:00
dockerfiles Strip unused SDK components to reduce image size 2026-02-03 17:17:44 -05:00
.gitignore Initial commit: multi-version .NET Docker images with apko base 2026-02-03 15:18:15 -05:00
DOCKERHUB.md Run SDK image as nonroot (UID 65532) for Docker Scout compliance 2026-02-03 15:39:51 -05:00
Makefile Initial commit: multi-version .NET Docker images with apko base 2026-02-03 15:18:15 -05:00
README.md Run SDK image as nonroot (UID 65532) for Docker Scout compliance 2026-02-03 15:39:51 -05:00

.NET Docker Images

Git Repository Docker Hub Docker Pulls .NET Wolfi

Minimal .NET Docker images for production and CI/CD. Built on Wolfi, a security-focused Linux distribution designed for containers. All supported (non-EOL) .NET versions are rebuilt automatically.

Images

Version runtime runtime-invariant sdk Arch EOL
.NET 10 (LTS) runtime-10 runtime-lts runtime-invariant-10 runtime-invariant-lts sdk-10 sdk-lts amd64 arm64 2028-11-14
.NET 9 (STS) runtime-9 runtime-sts runtime-invariant-9 runtime-invariant-sts sdk-9 sdk-sts amd64 arm64 2026-11-10
.NET 8 runtime-8 runtime-invariant-8 sdk-8 amd64 arm64 2026-11-10

Variants

Variant Includes Shell ICU/Globalization User
runtime ASP.NET Core runtime No Yes 65532 (nonroot)
runtime-invariant ASP.NET Core runtime No No (invariant mode) 65532 (nonroot)
sdk .NET SDK + bash, git, curl Yes (bash) Yes 65532 (nonroot)
  • runtime - Full globalization support (ICU + tzdata). Use this for apps that need locale-aware formatting, time zones, or culture-specific behavior.
  • runtime-invariant - No ICU or tzdata. Smallest image size. Use this for APIs that only need UTC and ordinal string comparison.
  • sdk - Everything needed to build .NET apps. Uses DOTNET_CLI_HOME=/home/nonroot for NuGet cache — no root required. Use COPY --chown=nonroot to make source files writable.

Why Wolfi?

Wolfi is a lightweight Linux distribution built specifically for containers. It provides:

  • Minimal footprint - Only essential packages, nothing extra
  • Daily security updates - Patches applied quickly
  • Designed for containers - No legacy cruft from traditional distros

Features

  • Lightweight - Optimized for fast CI/CD pulls
  • Secure - Built on Wolfi with continuous vulnerability scanning
  • Multi-arch - Supports both linux/amd64 and linux/arm64
  • Non-root - Runtime images run as unprivileged user (UID 65532)
  • Supply chain security - SBOM and SLSA provenance attestations included
  • EOL-aware - Versions are automatically dropped when they reach end-of-life

Dockerfile Examples

ARG BUILDPLATFORM
FROM --platform=$BUILDPLATFORM svrnty/dotnet:sdk-10 AS build

WORKDIR /app/source
COPY --chown=nonroot . .
WORKDIR /app/source/MyApp.Api

ARG TARGETARCH
RUN case "$TARGETARCH" in \
      amd64) ARCH=x64 ;; \
      arm64) ARCH=arm64 ;; \
      *) ARCH=$TARGETARCH ;; \
    esac && \
    dotnet publish -a $ARCH --self-contained false -o /app/publish

FROM svrnty/dotnet:runtime-invariant-10 AS final
WORKDIR /app
COPY --from=build /app/publish .
USER 65532
EXPOSE 8080
ENTRYPOINT ["/usr/share/dotnet/dotnet", "MyApp.Api.dll"]

Web API with globalization (ICU)

ARG BUILDPLATFORM
FROM --platform=$BUILDPLATFORM svrnty/dotnet:sdk-lts AS build

WORKDIR /app/source
COPY --chown=nonroot . .

ARG TARGETARCH
RUN case "$TARGETARCH" in \
      amd64) ARCH=x64 ;; \
      arm64) ARCH=arm64 ;; \
      *) ARCH=$TARGETARCH ;; \
    esac && \
    dotnet publish MyApp.sln -a $ARCH --self-contained false -o /app/publish

FROM svrnty/dotnet:runtime-lts AS final
WORKDIR /app
COPY --from=build /app/publish .
USER 65532
EXPOSE 8080
ENTRYPOINT ["/usr/share/dotnet/dotnet", "MyApp.dll"]

Worker service

ARG BUILDPLATFORM
FROM --platform=$BUILDPLATFORM svrnty/dotnet:sdk-10 AS build

WORKDIR /app/source
COPY --chown=nonroot . .

ARG TARGETARCH
RUN case "$TARGETARCH" in \
      amd64) ARCH=x64 ;; \
      arm64) ARCH=arm64 ;; \
      *) ARCH=$TARGETARCH ;; \
    esac && \
    dotnet publish MyWorker -a $ARCH --self-contained false -o /app/publish

FROM svrnty/dotnet:runtime-invariant-10 AS final
WORKDIR /app
COPY --from=build /app/publish .
USER 65532
ENTRYPOINT ["/usr/share/dotnet/dotnet", "MyWorker.dll"]

CI/CD (Gitea/GitHub Actions)

jobs:
  build:
    runs-on: ubuntu-latest
    container:
      image: svrnty/dotnet:sdk-lts
    steps:
      - uses: actions/checkout@v4
      - run: dotnet restore
      - run: dotnet test --no-restore
      - run: dotnet publish -c Release -o /app

Tags

Each variant is tagged with:

  • <variant>-<major> - Latest patch for a major version (e.g., runtime-10)
  • <variant>-<version> - Exact version pin (e.g., runtime-10.0.2, sdk-10.0.102)
  • <variant>-lts - Floating tag pointing to the highest active LTS (currently .NET 10)
  • <variant>-sts - Floating tag pointing to the highest active STS (currently .NET 9)

Automatic Updates

Images are automatically rebuilt when:

  • New .NET patch versions are released (daily check)
  • Base image security updates are available (weekly rebuild)
  • A .NET version reaches EOL, it is automatically excluded

Every build is scanned with Docker Scout and includes supply chain attestations (SBOM, SLSA provenance).

License

MIT