From a021c68d952e1a4c0b55a214eb770b9e29f4ed52 Mon Sep 17 00:00:00 2001 From: John Simons Date: Mon, 24 Feb 2025 10:47:08 +1000 Subject: [PATCH 1/2] Improving provenance of image Using native action to login to ghcr.io Replaced multiple tagging commands with a single one Using build-push-action instead of script This adds the provenance by default, see https://docs.docker.com/build/ci/github-actions/attestations/#default-provenance This given the image a better score in DockerHub scout health score --- .github/workflows/push-container-images.yml | 27 ++++++------ .github/workflows/release.yml | 47 ++++++++++----------- src/ServicePulse/Dockerfile | 20 ++++++--- 3 files changed, 49 insertions(+), 45 deletions(-) diff --git a/.github/workflows/push-container-images.yml b/.github/workflows/push-container-images.yml index 6ac87a161..ae2a80f5b 100644 --- a/.github/workflows/push-container-images.yml +++ b/.github/workflows/push-container-images.yml @@ -22,29 +22,28 @@ jobs: with: version: ${{ inputs.version }} - name: Log in to GitHub container registry - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} - name: Login to Docker Hub - uses: docker/login-action@v3.3.0 + uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 - name: Publish to Docker Hub run: | - $containers = @('servicepulse') $tags = "${{ steps.validate.outputs.container-tags }}" -Split ',' $sourceTag = "${{ inputs.version }}" - foreach ($tag in $tags) - { - foreach($name in $containers) - { - Write-Output "::group::Pushing $($name):$($tag)" - $cmd = "docker buildx imagetools create --tag particular/$($name):$($tag) ghcr.io/particular/$($name):$($sourceTag)" - Write-Output "Command: $cmd" - Invoke-Expression $cmd - Write-Output "::endgroup::" - } - } + $tagsCLI = $tags -replace "^", "--tag particular/servicepulse:" + + $cmd = "docker buildx imagetools create $tagsCLI ghcr.io/particular/servicepulse:$sourceTag" + Write-Output "Command: $cmd" + Invoke-Expression $cmd - name: Update Docker Hub Description if: ${{ steps.validate.outputs.latest == 'true' }} uses: peter-evans/dockerhub-description@v4.0.0 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1c2e78a36..d1aa7f765 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -140,28 +140,27 @@ jobs: with: version: ${{ env.MinVerVersion }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3.7.1 + uses: docker/setup-buildx-action@v3 - name: Log in to GitHub container registry - shell: bash - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - - name: Build & inspect image - env: - TAG_NAME: ${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || env.MinVerVersion }} - shell: bash - run: | - docker buildx build --push --tag ghcr.io/particular/servicepulse:${{ env.TAG_NAME }} \ - --file src/ServicePulse/Dockerfile \ - --build-arg VERSION=${{ env.MinVerVersion }} \ - --annotation "index:org.opencontainers.image.title=ServicePulse" \ - --annotation "index:org.opencontainers.image.description=ServicePulse provides real-time production monitoring for distributed applications. It monitors the health of a system's endpoints, detects processing errors, sends failed messages for reprocessing, and ensures the specific environment's needs are met, all in one consolidated dashboard." \ - --annotation "index:org.opencontainers.image.created=$(date '+%FT%TZ')" \ - --annotation "index:org.opencontainers.image.revision=${{ github.sha }}" \ - --annotation "index:org.opencontainers.image.authors=Particular Software" \ - --annotation "index:org.opencontainers.image.vendor=Particular Software" \ - --annotation "index:org.opencontainers.image.version=${{ env.MinVerVersion }}" \ - --annotation "index:org.opencontainers.image.source=https://github.com/${{ github.repository }}/tree/${{ github.sha }}" \ - --annotation "index:org.opencontainers.image.url=https://hub.docker.com/r/particular/servicepulse" \ - --annotation "index:org.opencontainers.image.documentation=https://docs.particular.net/servicepulse/" \ - --annotation "index:org.opencontainers.image.base.name=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite" \ - --platform linux/arm64,linux/amd64 . - docker buildx imagetools inspect ghcr.io/particular/servicepulse:${{ env.TAG_NAME }} + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Get current date + id: date + run: echo "date=$(date '+%FT%TZ')" >> $GITHUB_OUTPUT + - name: Build and push image to GitHub container registry + uses: docker/build-push-action@v6 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + sbom: true + build-args: | + VERSION=${{ env.MinVerVersion }} + SHA=${{ github.sha }} + CREATED=${{ steps.date.outputs.date }} + file: src/ServicePulse/Dockerfile + tags: ghcr.io/particular/servicepulse:${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || env.MinVerVersion }} + diff --git a/src/ServicePulse/Dockerfile b/src/ServicePulse/Dockerfile index 4679a29ce..022389208 100644 --- a/src/ServicePulse/Dockerfile +++ b/src/ServicePulse/Dockerfile @@ -17,15 +17,21 @@ RUN dotnet publish src/ServicePulse/ServicePulse.csproj -a $TARGETARCH -o /app # Host runtime image FROM mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite ARG VERSION +ARG SHA=unknown +ARG CREATED=2000-01-01T00:00:00Z WORKDIR /app -LABEL org.opencontainers.image.source="https://github.com/particular/servicepulse" \ - org.opencontainers.image.authors="Particular Software" \ - org.opencontainers.image.url=https://docs.particular.net/servicepulse/ \ - org.opencontainers.image.documentation="https://docs.particular.net/servicepulse/" \ - org.opencontainers.image.version=$VERSION \ - org.opencontainers.image.title="ServicePulse" \ - org.opencontainers.image.description="ServicePulse provides real-time production monitoring for distributed applications. It monitors the health of a system's endpoints, detects processing errors, sends failed messages for reprocessing, and ensures the specific environment's needs are met, all in one consolidated dashboard." +LABEL org.opencontainers.image.source=https://github.com/Particular/servicepulse/tree/$SHA +LABEL org.opencontainers.image.authors="Particular Software" +LABEL org.opencontainers.image.vendor="Particular Software" +LABEL org.opencontainers.image.url=https://hub.docker.com/r/particular/servicepulse +LABEL org.opencontainers.image.documentation=https://docs.particular.net/servicepulse/ +LABEL org.opencontainers.image.version=$VERSION +LABEL org.opencontainers.image.revision=$SHA +LABEL org.opencontainers.image.created=$CREATED +LABEL org.opencontainers.image.title="ServicePulse" +LABEL org.opencontainers.image.description="ServicePulse provides real-time production monitoring for distributed applications. It monitors the health of a system's endpoints, detects processing errors, sends failed messages for reprocessing, and ensures the specific environment's needs are met, all in one consolidated dashboard." +LABEL org.opencontainers.image.base.name=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite ENV ASPNETCORE_HTTP_PORTS=9090 EXPOSE 9090 From 9d201b464b99d3207a1c261fffb20471eb9e935b Mon Sep 17 00:00:00 2001 From: John Simons Date: Wed, 26 Feb 2025 09:27:17 +1000 Subject: [PATCH 2/2] A few updates based on feedback --- .github/workflows/push-container-images.yml | 6 ++-- .github/workflows/release.yml | 34 ++++++++++++++++----- src/ServicePulse/Dockerfile | 15 --------- 3 files changed, 30 insertions(+), 25 deletions(-) diff --git a/.github/workflows/push-container-images.yml b/.github/workflows/push-container-images.yml index ae2a80f5b..19264fcf3 100644 --- a/.github/workflows/push-container-images.yml +++ b/.github/workflows/push-container-images.yml @@ -22,18 +22,18 @@ jobs: with: version: ${{ inputs.version }} - name: Log in to GitHub container registry - uses: docker/login-action@v3 + uses: docker/login-action@v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - name: Login to Docker Hub - uses: docker/login-action@v3 + uses: docker/login-action@v3.3.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v3.9.0 - name: Publish to Docker Hub run: | $tags = "${{ steps.validate.outputs.container-tags }}" -Split ',' diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d1aa7f765..418a156ed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -140,9 +140,9 @@ jobs: with: version: ${{ env.MinVerVersion }} - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v3.9.0 - name: Log in to GitHub container registry - uses: docker/login-action@v3 + uses: docker/login-action@v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} @@ -151,16 +151,36 @@ jobs: id: date run: echo "date=$(date '+%FT%TZ')" >> $GITHUB_OUTPUT - name: Build and push image to GitHub container registry - uses: docker/build-push-action@v6 + uses: docker/build-push-action@v6.14.0 with: context: . push: true platforms: linux/amd64,linux/arm64 sbom: true - build-args: | - VERSION=${{ env.MinVerVersion }} - SHA=${{ github.sha }} - CREATED=${{ steps.date.outputs.date }} + labels: | + org.opencontainers.image.source=https://github.com/Particular/ServicePulse/tree/${{ github.sha }} + org.opencontainers.image.authors="Particular Software" + org.opencontainers.image.vendor="Particular Software" + org.opencontainers.image.url=https://hub.docker.com/r/particular/servicepulse + org.opencontainers.image.documentation=https://docs.particular.net/servicepulse/ + org.opencontainers.image.version=${{ env.MinVerVersion }} + org.opencontainers.image.revision=${{ github.sha }} + org.opencontainers.image.created=${{ steps.date.outputs.date }} + org.opencontainers.image.title=ServicePulse + org.opencontainers.image.description=ServicePulse provides real-time production monitoring for distributed applications. It monitors the health of a system's endpoints, detects processing errors, sends failed messages for reprocessing, and ensures the specific environment's needs are met, all in one consolidated dashboard. + org.opencontainers.image.base.name=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite + annotations: | + index:org.opencontainers.image.source=https://github.com/Particular/ServicePulse/tree/${{ github.sha }} + index:org.opencontainers.image.authors="Particular Software" + index:org.opencontainers.image.vendor="Particular Software" + index:org.opencontainers.image.url=https://hub.docker.com/r/particular/servicepulse + index:org.opencontainers.image.documentation=https://docs.particular.net/servicepulse/ + index:org.opencontainers.image.version=${{ env.MinVerVersion }} + index:org.opencontainers.image.revision=${{ github.sha }} + index:org.opencontainers.image.created=${{ steps.date.outputs.date }} + index:org.opencontainers.image.title=ServicePulse + index:org.opencontainers.image.description=ServicePulse provides real-time production monitoring for distributed applications. It monitors the health of a system's endpoints, detects processing errors, sends failed messages for reprocessing, and ensures the specific environment's needs are met, all in one consolidated dashboard. + index:org.opencontainers.image.base.name=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite file: src/ServicePulse/Dockerfile tags: ghcr.io/particular/servicepulse:${{ github.event_name == 'pull_request' && format('pr-{0}', github.event.number) || env.MinVerVersion }} diff --git a/src/ServicePulse/Dockerfile b/src/ServicePulse/Dockerfile index 022389208..16228dd36 100644 --- a/src/ServicePulse/Dockerfile +++ b/src/ServicePulse/Dockerfile @@ -16,23 +16,8 @@ RUN dotnet publish src/ServicePulse/ServicePulse.csproj -a $TARGETARCH -o /app # Host runtime image FROM mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite -ARG VERSION -ARG SHA=unknown -ARG CREATED=2000-01-01T00:00:00Z WORKDIR /app -LABEL org.opencontainers.image.source=https://github.com/Particular/servicepulse/tree/$SHA -LABEL org.opencontainers.image.authors="Particular Software" -LABEL org.opencontainers.image.vendor="Particular Software" -LABEL org.opencontainers.image.url=https://hub.docker.com/r/particular/servicepulse -LABEL org.opencontainers.image.documentation=https://docs.particular.net/servicepulse/ -LABEL org.opencontainers.image.version=$VERSION -LABEL org.opencontainers.image.revision=$SHA -LABEL org.opencontainers.image.created=$CREATED -LABEL org.opencontainers.image.title="ServicePulse" -LABEL org.opencontainers.image.description="ServicePulse provides real-time production monitoring for distributed applications. It monitors the health of a system's endpoints, detects processing errors, sends failed messages for reprocessing, and ensures the specific environment's needs are met, all in one consolidated dashboard." -LABEL org.opencontainers.image.base.name=mcr.microsoft.com/dotnet/aspnet:8.0-noble-chiseled-composite - ENV ASPNETCORE_HTTP_PORTS=9090 EXPOSE 9090 COPY --from=build /app .