From 0b301121ad746b2aceb5aa74b219e7ccd0467ff2 Mon Sep 17 00:00:00 2001 From: Mathias Beaulieu-Duncan Date: Tue, 3 Feb 2026 15:18:15 -0500 Subject: [PATCH] Initial commit: multi-version .NET Docker images with apko base - apko configs for runtime (ICU), runtime-invariant (no ICU), and SDK variants - Build workflow with dynamic matrix from .NET release metadata (EOL-aware) - Daily update-check workflow to detect new .NET versions - Docker Scout PR analysis workflow - LTS/STS floating tags, multi-arch (amd64 + arm64) - Makefile for local builds and version discovery Co-Authored-By: Claude Opus 4.5 --- .gitea/workflows/build.yaml | 245 +++++++++++++++++++++++ .gitea/workflows/scout.yaml | 115 +++++++++++ .gitea/workflows/update-check.yaml | 74 +++++++ .gitignore | 5 + Makefile | 55 +++++ apko/runtime-invariant.yaml | 30 +++ apko/runtime.yaml | 32 +++ apko/sdk.yaml | 36 ++++ dockerfiles/runtime-invariant.Dockerfile | 10 + dockerfiles/runtime.Dockerfile | 10 + dockerfiles/sdk.Dockerfile | 10 + 11 files changed, 622 insertions(+) create mode 100644 .gitea/workflows/build.yaml create mode 100644 .gitea/workflows/scout.yaml create mode 100644 .gitea/workflows/update-check.yaml create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 apko/runtime-invariant.yaml create mode 100644 apko/runtime.yaml create mode 100644 apko/sdk.yaml create mode 100644 dockerfiles/runtime-invariant.Dockerfile create mode 100644 dockerfiles/runtime.Dockerfile create mode 100644 dockerfiles/sdk.Dockerfile diff --git a/.gitea/workflows/build.yaml b/.gitea/workflows/build.yaml new file mode 100644 index 0000000..e4494ca --- /dev/null +++ b/.gitea/workflows/build.yaml @@ -0,0 +1,245 @@ +name: Build and Push .NET Images + +on: + release: + types: [published] + workflow_dispatch: + schedule: + # Weekly rebuild for CVE patches (Sunday 6am UTC) + - cron: "0 6 * * 0" + +permissions: + id-token: write + contents: read + packages: write + +env: + DOCKER_IMAGE: docker.io/svrnty/dotnet + RELEASES_INDEX_URL: https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json + +jobs: + discover: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.discover.outputs.matrix }} + lts_major: ${{ steps.discover.outputs.lts_major }} + sts_major: ${{ steps.discover.outputs.sts_major }} + steps: + - name: Discover supported .NET versions + id: discover + run: | + set -euo pipefail + + RELEASES=$(curl -fsSL "$RELEASES_INDEX_URL") + + # Filter active/go-live versions (excludes EOL automatically) + SUPPORTED=$(echo "$RELEASES" | jq -c '[.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live")]') + + # Build matrix JSON + MATRIX=$(echo "$SUPPORTED" | jq -c '{include: [.[] | { + major: (.["channel-version"] | split(".")[0]), + runtime: .["latest-runtime"], + sdk: .["latest-sdk"], + type: .["release-type"] + }]}') + + # Find highest LTS and STS majors + LTS_MAJOR=$(echo "$SUPPORTED" | jq -r '[.[] | select(.["release-type"] == "lts")] | sort_by(.["channel-version"] | split(".") | map(tonumber)) | last | .["channel-version"] | split(".")[0]') + STS_MAJOR=$(echo "$SUPPORTED" | jq -r '[.[] | select(.["release-type"] == "sts")] | sort_by(.["channel-version"] | split(".") | map(tonumber)) | last | .["channel-version"] | split(".")[0] // ""') + + echo "matrix=$MATRIX" >> $GITHUB_OUTPUT + echo "lts_major=$LTS_MAJOR" >> $GITHUB_OUTPUT + echo "sts_major=$STS_MAJOR" >> $GITHUB_OUTPUT + + echo "Matrix: $MATRIX" + echo "LTS major: $LTS_MAJOR" + echo "STS major: $STS_MAJOR" + + build: + runs-on: ubuntu-latest + needs: discover + strategy: + fail-fast: false + matrix: ${{ fromJson(needs.discover.outputs.matrix) }} + env: + LTS_MAJOR: ${{ needs.discover.outputs.lts_major }} + STS_MAJOR: ${{ needs.discover.outputs.sts_major }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_SVRNTY_USERNAME }} + password: ${{ secrets.DOCKERHUB_SVRNTY_ACCESS_TOKEN }} + + - name: Build apko base images + run: | + set -euo pipefail + + for VARIANT in runtime runtime-invariant sdk; do + for ARCH in x86_64 aarch64; do + echo "::group::Building apko base: $VARIANT ($ARCH)" + mkdir -p ${{ github.workspace }}/build-${ARCH}/${VARIANT} + docker run --rm \ + -v ${{ github.workspace }}/apko:/work:ro \ + -v ${{ github.workspace }}/build-${ARCH}/${VARIANT}:/output \ + cgr.dev/chainguard/apko build \ + --arch $ARCH /work/${VARIANT}.yaml ${VARIANT}:latest /output/rootfs.tar.gz + echo "::endgroup::" + done + done + + - name: Download .NET binaries + run: | + set -euo pipefail + + RUNTIME_VERSION="${{ matrix.runtime }}" + SDK_VERSION="${{ matrix.sdk }}" + + for ARCH in x86_64 aarch64; do + if [ "$ARCH" = "x86_64" ]; then + DOTNET_ARCH="x64" + PLATFORM_ARCH="amd64" + else + DOTNET_ARCH="arm64" + PLATFORM_ARCH="arm64" + fi + + # Download ASP.NET Core runtime (for runtime and runtime-invariant) + echo "::group::Downloading ASP.NET Core runtime $RUNTIME_VERSION ($DOTNET_ARCH)" + mkdir -p dotnet-${PLATFORM_ARCH}/runtime + curl -fsSL "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/${RUNTIME_VERSION}/aspnetcore-runtime-${RUNTIME_VERSION}-linux-${DOTNET_ARCH}.tar.gz" \ + -o /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz + tar xf /tmp/aspnet-runtime-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/runtime + echo "::endgroup::" + + # Download .NET SDK + echo "::group::Downloading .NET SDK $SDK_VERSION ($DOTNET_ARCH)" + mkdir -p dotnet-${PLATFORM_ARCH}/sdk + curl -fsSL "https://dotnetcli.azureedge.net/dotnet/Sdk/${SDK_VERSION}/dotnet-sdk-${SDK_VERSION}-linux-${DOTNET_ARCH}.tar.gz" \ + -o /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz + tar xf /tmp/dotnet-sdk-${PLATFORM_ARCH}.tar.gz -C dotnet-${PLATFORM_ARCH}/sdk + echo "::endgroup::" + done + + - name: Build and push runtime image + run: | + set -euo pipefail + + MAJOR="${{ matrix.major }}" + VERSION="${{ matrix.runtime }}" + VARIANT="runtime" + + # Prepare build context + mkdir -p context-runtime + for ARCH in amd64 arm64; do + APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64") + mkdir -p context-runtime/build-${ARCH}/runtime + cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-runtime/build-${ARCH}/runtime/ + mkdir -p context-runtime/dotnet-${ARCH} + cp -r dotnet-${ARCH}/runtime context-runtime/dotnet-${ARCH}/ + done + cp dockerfiles/runtime.Dockerfile context-runtime/Dockerfile + + # Determine tags + TAGS="-t $DOCKER_IMAGE:${VARIANT}-${MAJOR} -t $DOCKER_IMAGE:${VARIANT}-${VERSION}" + if [ "$MAJOR" = "$LTS_MAJOR" ]; then + TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-lts" + fi + if [ "$MAJOR" = "$STS_MAJOR" ]; then + TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-sts" + fi + + echo "Building $VARIANT with tags: $TAGS" + docker buildx build --platform linux/amd64,linux/arm64 --push \ + --sbom=true --provenance=mode=max \ + $TAGS \ + context-runtime/ + + - name: Build and push runtime-invariant image + run: | + set -euo pipefail + + MAJOR="${{ matrix.major }}" + VERSION="${{ matrix.runtime }}" + VARIANT="runtime-invariant" + + mkdir -p context-runtime-invariant + for ARCH in amd64 arm64; do + APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64") + mkdir -p context-runtime-invariant/build-${ARCH}/runtime-invariant + cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-runtime-invariant/build-${ARCH}/runtime-invariant/ + mkdir -p context-runtime-invariant/dotnet-${ARCH} + cp -r dotnet-${ARCH}/runtime context-runtime-invariant/dotnet-${ARCH}/ + done + cp dockerfiles/runtime-invariant.Dockerfile context-runtime-invariant/Dockerfile + + TAGS="-t $DOCKER_IMAGE:${VARIANT}-${MAJOR} -t $DOCKER_IMAGE:${VARIANT}-${VERSION}" + if [ "$MAJOR" = "$LTS_MAJOR" ]; then + TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-lts" + fi + if [ "$MAJOR" = "$STS_MAJOR" ]; then + TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-sts" + fi + + echo "Building $VARIANT with tags: $TAGS" + docker buildx build --platform linux/amd64,linux/arm64 --push \ + --sbom=true --provenance=mode=max \ + $TAGS \ + context-runtime-invariant/ + + - name: Build and push SDK image + run: | + set -euo pipefail + + MAJOR="${{ matrix.major }}" + VERSION="${{ matrix.sdk }}" + VARIANT="sdk" + + mkdir -p context-sdk + for ARCH in amd64 arm64; do + APKO_ARCH=$([[ "$ARCH" == "amd64" ]] && echo "x86_64" || echo "aarch64") + mkdir -p context-sdk/build-${ARCH}/sdk + cp build-${APKO_ARCH}/${VARIANT}/rootfs.tar.gz context-sdk/build-${ARCH}/sdk/ + mkdir -p context-sdk/dotnet-${ARCH} + cp -r dotnet-${ARCH}/sdk context-sdk/dotnet-${ARCH}/ + done + cp dockerfiles/sdk.Dockerfile context-sdk/Dockerfile + + TAGS="-t $DOCKER_IMAGE:${VARIANT}-${MAJOR} -t $DOCKER_IMAGE:${VARIANT}-${VERSION}" + if [ "$MAJOR" = "$LTS_MAJOR" ]; then + TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-lts" + fi + if [ "$MAJOR" = "$STS_MAJOR" ]; then + TAGS="$TAGS -t $DOCKER_IMAGE:${VARIANT}-sts" + fi + + echo "Building $VARIANT with tags: $TAGS" + docker buildx build --platform linux/amd64,linux/arm64 --push \ + --sbom=true --provenance=mode=max \ + $TAGS \ + context-sdk/ + + - name: Install Docker Scout + run: | + curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh + sh install-scout.sh + + - name: Docker Scout CVE Scan + run: | + MAJOR="${{ matrix.major }}" + for VARIANT in runtime runtime-invariant sdk; do + echo "::group::Scout scan: ${VARIANT}-${MAJOR}" + docker scout cves ${{ env.DOCKER_IMAGE }}:${VARIANT}-${MAJOR} --only-severity critical,high || true + echo "::endgroup::" + done diff --git a/.gitea/workflows/scout.yaml b/.gitea/workflows/scout.yaml new file mode 100644 index 0000000..0611432 --- /dev/null +++ b/.gitea/workflows/scout.yaml @@ -0,0 +1,115 @@ +name: Docker Scout Analysis + +on: + pull_request: + branches: ["**"] + +permissions: + contents: read + pull-requests: write + +env: + DOCKER_IMAGE: docker.io/svrnty/dotnet + +jobs: + check-image: + runs-on: ubuntu-latest + outputs: + image_exists: ${{ steps.check.outputs.exists }} + steps: + - name: Log in to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_SVRNTY_USERNAME }} + password: ${{ secrets.DOCKERHUB_SVRNTY_ACCESS_TOKEN }} + + - name: Check if latest runtime-lts image exists + id: check + run: | + if docker manifest inspect ${{ env.DOCKER_IMAGE }}:runtime-lts > /dev/null 2>&1; then + echo "exists=true" >> $GITHUB_OUTPUT + echo "Latest runtime-lts image found, Scout compare will run" + else + echo "exists=false" >> $GITHUB_OUTPUT + echo "No runtime-lts image found, skipping Scout compare" + fi + + scout: + runs-on: ubuntu-latest + needs: check-image + if: needs.check-image.outputs.image_exists == 'true' + strategy: + matrix: + arch: [amd64, arm64] + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up QEMU + if: matrix.arch == 'arm64' + uses: docker/setup-qemu-action@v3 + with: + platforms: arm64 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_SVRNTY_USERNAME }} + password: ${{ secrets.DOCKERHUB_SVRNTY_ACCESS_TOKEN }} + + - name: Discover latest LTS version + id: discover + run: | + set -euo pipefail + RELEASES=$(curl -fsSL https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json) + SUPPORTED=$(echo "$RELEASES" | jq -c '[.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live")]') + + # Find highest LTS major + LTS_MAJOR=$(echo "$SUPPORTED" | jq -r '[.[] | select(.["release-type"] == "lts")] | sort_by(.["channel-version"] | split(".") | map(tonumber)) | last | .["channel-version"] | split(".")[0]') + LTS_RUNTIME=$(echo "$SUPPORTED" | jq -r --arg ch "${LTS_MAJOR}.0" '.[] | select(.["channel-version"] == $ch) | .["latest-runtime"]') + + echo "lts_major=$LTS_MAJOR" >> $GITHUB_OUTPUT + echo "lts_runtime=$LTS_RUNTIME" >> $GITHUB_OUTPUT + + - name: Build test image (${{ matrix.arch }}) + run: | + # Build apko base + docker run --rm -v ${{ github.workspace }}/apko:/work cgr.dev/chainguard/apko build \ + --arch ${{ matrix.arch == 'amd64' && 'x86_64' || 'aarch64' }} \ + /work/runtime.yaml runtime:latest /tmp/rootfs.tar.gz + + # Download .NET runtime + DOTNET_ARCH=${{ matrix.arch == 'amd64' && 'x64' || 'arm64' }} + RUNTIME_VERSION=${{ steps.discover.outputs.lts_runtime }} + curl -fsSL "https://dotnetcli.azureedge.net/dotnet/aspnetcore/Runtime/${RUNTIME_VERSION}/aspnetcore-runtime-${RUNTIME_VERSION}-linux-${DOTNET_ARCH}.tar.gz" \ + -o /tmp/dotnet.tar.gz + mkdir -p /tmp/dotnet + tar xf /tmp/dotnet.tar.gz -C /tmp/dotnet + + # Build image + cat > /tmp/Dockerfile <<'DOCKERFILE' + FROM scratch + ADD rootfs.tar.gz / + COPY dotnet/ /usr/share/dotnet/ + ENV DOTNET_ROOT=/usr/share/dotnet + ENV PATH="/usr/share/dotnet:${PATH}" + WORKDIR /app + USER 65532 + DOCKERFILE + + docker build -t ${{ env.DOCKER_IMAGE }}:pr-${{ github.event.pull_request.number }}-${{ matrix.arch }} /tmp/ + + - name: Install Docker Scout + run: | + curl -fsSL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh -o install-scout.sh + sh install-scout.sh + + - name: Docker Scout Compare (${{ matrix.arch }}) + run: | + docker scout compare \ + ${{ env.DOCKER_IMAGE }}:pr-${{ github.event.pull_request.number }}-${{ matrix.arch }} \ + --to ${{ env.DOCKER_IMAGE }}:runtime-lts \ + --ignore-unchanged --only-severity critical,high diff --git a/.gitea/workflows/update-check.yaml b/.gitea/workflows/update-check.yaml new file mode 100644 index 0000000..cb56ec9 --- /dev/null +++ b/.gitea/workflows/update-check.yaml @@ -0,0 +1,74 @@ +name: Daily .NET Version Check + +on: + schedule: + - cron: "0 8 * * *" + workflow_dispatch: + +env: + DOCKER_IMAGE: docker.io/svrnty/dotnet + RELEASES_INDEX_URL: https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json + +jobs: + check-versions: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Log in to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_SVRNTY_USERNAME }} + password: ${{ secrets.DOCKERHUB_SVRNTY_ACCESS_TOKEN }} + + - name: Check for new .NET versions + id: check + run: | + set -euo pipefail + + # Fetch release metadata + RELEASES=$(curl -fsSL "$RELEASES_INDEX_URL") + + # Filter active/go-live versions (excludes EOL automatically) + SUPPORTED=$(echo "$RELEASES" | jq -c '[.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live")]') + + NEEDS_BUILD=false + + echo "$SUPPORTED" | jq -r '.[] | "\(.["channel-version"]) \(.["latest-runtime"]) \(.["latest-sdk"]) \(.["release-type"])"' | \ + while read -r CHANNEL RUNTIME SDK TYPE; do + MAJOR=$(echo "$CHANNEL" | cut -d. -f1) + echo "Checking .NET $MAJOR: runtime=$RUNTIME sdk=$SDK type=$TYPE" + + # Check if runtime image for this exact version exists + if docker manifest inspect "$DOCKER_IMAGE:runtime-$RUNTIME" > /dev/null 2>&1; then + echo " Image runtime-$RUNTIME already exists, skipping" + else + echo " New version detected: runtime-$RUNTIME" + NEEDS_BUILD=true + fi + done + + # Re-check outside the pipe (subshell issue) + NEEDS_BUILD=false + while read -r CHANNEL RUNTIME SDK TYPE; do + MAJOR=$(echo "$CHANNEL" | cut -d. -f1) + if ! docker manifest inspect "$DOCKER_IMAGE:runtime-$RUNTIME" > /dev/null 2>&1; then + NEEDS_BUILD=true + break + fi + done < <(echo "$SUPPORTED" | jq -r '.[] | "\(.["channel-version"]) \(.["latest-runtime"]) \(.["latest-sdk"]) \(.["release-type"])"') + + echo "needs_build=$NEEDS_BUILD" >> $GITHUB_OUTPUT + + - name: Trigger build workflow + if: steps.check.outputs.needs_build == 'true' + uses: actions/github-script@v7 + with: + script: | + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'build.yaml', + ref: context.ref + }) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..894e6d9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +build-*/ +dotnet-*/ +context-*/ +*.tar.gz +.env diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..4926fcd --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +DOCKER_IMAGE := svrnty/dotnet +VARIANTS := runtime runtime-invariant sdk + +# Default: show help +.PHONY: help +help: + @echo "Usage:" + @echo " make discover - Query .NET release metadata and show supported versions" + @echo " make build-apko - Build all apko base images locally" + @echo " make build MAJOR=10 - Build all variants for a specific .NET major version" + @echo " make clean - Remove build artifacts" + +# Discover supported .NET versions from release metadata +.PHONY: discover +discover: + @echo "Fetching .NET release metadata..." + @curl -fsSL https://dotnetcli.azureedge.net/dotnet/release-metadata/releases-index.json | \ + jq -r '.["releases-index"][] | select(.["support-phase"] == "active" or .["support-phase"] == "go-live") | "\(.["channel-version"])\t\(.["latest-runtime"])\t\(.["latest-sdk"])\t\(.["release-type"])\t\(.["support-phase"])"' | \ + column -t -s$$'\t' -N "CHANNEL,RUNTIME,SDK,TYPE,PHASE" + +# Build apko base images for a specific variant (local only) +.PHONY: build-apko +build-apko: + @for variant in $(VARIANTS); do \ + echo "Building apko base: $$variant"; \ + for arch in x86_64 aarch64; do \ + docker run --rm -v $(PWD)/apko:/work cgr.dev/chainguard/apko build \ + --arch $$arch /work/$$variant.yaml $$variant:latest build-$$arch/$$variant.tar.gz || exit 1; \ + done; \ + done + +# Build all variants for a .NET major version +.PHONY: build +build: +ifndef MAJOR + $(error MAJOR is required, e.g. make build MAJOR=10) +endif + @echo "Building .NET $(MAJOR) images..." + @$(MAKE) build-variant VARIANT=runtime MAJOR=$(MAJOR) + @$(MAKE) build-variant VARIANT=runtime-invariant MAJOR=$(MAJOR) + @$(MAKE) build-variant VARIANT=sdk MAJOR=$(MAJOR) + +# Build a single variant (internal target) +.PHONY: build-variant +build-variant: + @echo "Building $(VARIANT)-$(MAJOR)..." + @for arch in x86_64 aarch64; do \ + docker run --rm -v $(PWD)/apko:/work cgr.dev/chainguard/apko build \ + --arch $$arch /work/$(VARIANT).yaml $(VARIANT):latest build-$$arch/rootfs.tar.gz || exit 1; \ + done + +# Clean build artifacts +.PHONY: clean +clean: + rm -rf build-* dotnet-* diff --git a/apko/runtime-invariant.yaml b/apko/runtime-invariant.yaml new file mode 100644 index 0000000..7dbc8a9 --- /dev/null +++ b/apko/runtime-invariant.yaml @@ -0,0 +1,30 @@ +contents: + repositories: + - https://packages.wolfi.dev/os + keyring: + - https://packages.wolfi.dev/os/wolfi-signing.rsa.pub + packages: + - wolfi-baselayout + - glibc + - libstdc++ + - ca-certificates-bundle + - libssl3 + - zlib + +accounts: + groups: + - groupname: nonroot + gid: 65532 + users: + - username: nonroot + uid: 65532 + gid: 65532 + run-as: 65532 + +archs: + - x86_64 + - aarch64 + +environment: + DOTNET_RUNNING_IN_CONTAINER: "true" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "true" diff --git a/apko/runtime.yaml b/apko/runtime.yaml new file mode 100644 index 0000000..3f4074b --- /dev/null +++ b/apko/runtime.yaml @@ -0,0 +1,32 @@ +contents: + repositories: + - https://packages.wolfi.dev/os + keyring: + - https://packages.wolfi.dev/os/wolfi-signing.rsa.pub + packages: + - wolfi-baselayout + - glibc + - libstdc++ + - ca-certificates-bundle + - libssl3 + - zlib + - icu + - tzdata + +accounts: + groups: + - groupname: nonroot + gid: 65532 + users: + - username: nonroot + uid: 65532 + gid: 65532 + run-as: 65532 + +archs: + - x86_64 + - aarch64 + +environment: + DOTNET_RUNNING_IN_CONTAINER: "true" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "false" diff --git a/apko/sdk.yaml b/apko/sdk.yaml new file mode 100644 index 0000000..612b227 --- /dev/null +++ b/apko/sdk.yaml @@ -0,0 +1,36 @@ +contents: + repositories: + - https://packages.wolfi.dev/os + keyring: + - https://packages.wolfi.dev/os/wolfi-signing.rsa.pub + packages: + - wolfi-baselayout + - glibc + - libstdc++ + - ca-certificates-bundle + - libssl3 + - zlib + - icu + - tzdata + - bash + - git + - curl + - coreutils + +accounts: + groups: + - groupname: nonroot + gid: 65532 + users: + - username: nonroot + uid: 65532 + gid: 65532 + run-as: 0 + +archs: + - x86_64 + - aarch64 + +environment: + DOTNET_RUNNING_IN_CONTAINER: "true" + DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "false" diff --git a/dockerfiles/runtime-invariant.Dockerfile b/dockerfiles/runtime-invariant.Dockerfile new file mode 100644 index 0000000..00ad5d0 --- /dev/null +++ b/dockerfiles/runtime-invariant.Dockerfile @@ -0,0 +1,10 @@ +FROM scratch +ARG TARGETARCH +ADD build-${TARGETARCH}/runtime-invariant/rootfs.tar.gz / +COPY dotnet-${TARGETARCH}/runtime/ /usr/share/dotnet/ +ENV DOTNET_ROOT=/usr/share/dotnet +ENV PATH="/usr/share/dotnet:${PATH}" +ENV DOTNET_RUNNING_IN_CONTAINER=true +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=true +WORKDIR /app +USER 65532 diff --git a/dockerfiles/runtime.Dockerfile b/dockerfiles/runtime.Dockerfile new file mode 100644 index 0000000..f1f6954 --- /dev/null +++ b/dockerfiles/runtime.Dockerfile @@ -0,0 +1,10 @@ +FROM scratch +ARG TARGETARCH +ADD build-${TARGETARCH}/runtime/rootfs.tar.gz / +COPY dotnet-${TARGETARCH}/runtime/ /usr/share/dotnet/ +ENV DOTNET_ROOT=/usr/share/dotnet +ENV PATH="/usr/share/dotnet:${PATH}" +ENV DOTNET_RUNNING_IN_CONTAINER=true +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false +WORKDIR /app +USER 65532 diff --git a/dockerfiles/sdk.Dockerfile b/dockerfiles/sdk.Dockerfile new file mode 100644 index 0000000..b1a5fd6 --- /dev/null +++ b/dockerfiles/sdk.Dockerfile @@ -0,0 +1,10 @@ +FROM scratch +ARG TARGETARCH +ADD build-${TARGETARCH}/sdk/rootfs.tar.gz / +COPY dotnet-${TARGETARCH}/sdk/ /usr/share/dotnet/ +ENV DOTNET_ROOT=/usr/share/dotnet +ENV PATH="/usr/share/dotnet:${PATH}" +ENV DOTNET_RUNNING_IN_CONTAINER=true +ENV DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=false +WORKDIR /app +USER 0