From 6b9a3e504443eb7ce07a7bf565b35292691e4f8e Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia <alessfg@hotmail.com> Date: Wed, 15 Jan 2025 21:06:03 +0100 Subject: [PATCH 1/7] ci: Build images across multiple runners --- .github/workflows/alpine-mainline.yml | 662 +++++++++++++++----------- 1 file changed, 397 insertions(+), 265 deletions(-) diff --git a/.github/workflows/alpine-mainline.yml b/.github/workflows/alpine-mainline.yml index 91ee2d2..b676d17 100644 --- a/.github/workflows/alpine-mainline.yml +++ b/.github/workflows/alpine-mainline.yml @@ -36,6 +36,8 @@ jobs: runs-on: ubuntu-24.04 strategy: fail-fast: false + matrix: + platform: [linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x] steps: - name: Check out the codebase uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 @@ -46,42 +48,42 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 - - name: Configure AWS credentials - if: ${{ github.event_name != 'pull_request' }} - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - aws-region: ${{ secrets.AWS_REGION }} - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + # - name: Configure AWS credentials + # if: ${{ github.event_name != 'pull_request' }} + # uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + # with: + # aws-region: ${{ secrets.AWS_REGION }} + # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + # aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - - name: Login to Amazon ECR Public Gallery - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: public.ecr.aws + # - name: Login to Amazon ECR Public Gallery + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: public.ecr.aws - name: Login to Docker Hub - if: ${{ github.event_name != 'pull_request' }} + # if: ${{ github.event_name != 'pull_request' }} uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to GitHub Container Registry - if: ${{ github.event_name != 'pull_request' }} + # if: ${{ github.event_name != 'pull_request' }} uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Login to Quay - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: quay.io - username: ${{ secrets.QUAY_USERNAME }} - password: ${{ secrets.QUAY_TOKEN }} + # - name: Login to Quay + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: quay.io + # username: ${{ secrets.QUAY_USERNAME }} + # password: ${{ secrets.QUAY_TOKEN }} - name: Extract metadata (annotations, labels, tags) for Docker id: meta @@ -90,8 +92,8 @@ jobs: images: | docker.io/nginxinc/nginx-unprivileged ghcr.io/nginxinc/nginx-unprivileged - public.ecr.aws/nginx/nginx-unprivileged - quay.io/nginx/nginx-unprivileged + # public.ecr.aws/nginx/nginx-unprivileged + # quay.io/nginx/nginx-unprivileged tags: | type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-slim type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-slim @@ -103,283 +105,413 @@ jobs: type=raw,value=mainline-alpine${{ needs.version.outputs.distro }}-slim type=raw,value=alpine-slim type=raw,value=alpine${{ needs.version.outputs.distro }}-slim - env: - DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + # env: + # DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - name: Build and push NGINX mainline slim Alpine image to Amazon ECR Public Gallery, Docker Hub, GitHub Container Registry, and Quay id: build uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 with: - platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x + platforms: ${{ matrix.platform }} context: "{{ defaultContext }}:mainline/alpine-slim" labels: ${{ steps.meta.outputs.labels }} annotations: ${{ steps.meta.outputs.annotations }} - tags: ${{ steps.meta.outputs.tags }} - push: ${{ github.event_name != 'pull_request' }} + # outputs: type=image,"name=ghcr.io/nginxinc/nginx-unprivileged,docker.io/nginxinc/nginx-unprivileged",push-by-digest=true,name-canonical=true,push=true + # outputs: type=image,"name=ghcr.io/nginxinc/nginx-unprivileged,docker.io/nginxinc/nginx-unprivileged",push-by-digest=true,name-canonical=true,push=true + outputs: type=docker,dest=${{ runner.temp }}/alpine-slim-${{ matrix.platform }}.tar + # tags: ${{ steps.meta.outputs.tags }} + # push: false + # push: ${{ github.event_name != 'pull_request' }} # cache-from: type=gha,scope=alpine-slim # cache-to: type=gha,mode=min,scope=alpine-slim - - name: Sign Docker Hub Manifest - if: ${{ github.event_name != 'pull_request' }} - run: | - set -ex - sudo apt update - sudo apt install -y notary - mkdir -p ~/.docker/trust/private - echo "$DOCKER_CONTENT_TRUST_REPOSITORY_KEY" > ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key - chmod 0400 ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key - docker trust key load ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key --name nginx - DIGEST=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".digest' | cut -d ':' -f2) - SIZE=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".size') - export NOTARY_AUTH=$(printf "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64 -w0) - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine-slim $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose - env: - DOCKER_CONTENT_TRUST_REPOSITORY_KEY: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY }} - DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID }} - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - NOTARY_TARGETS_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - core: - name: Build Alpine NGINX mainline Docker image - needs: [version, slim] - runs-on: ubuntu-24.04 - strategy: - fail-fast: false - steps: - - name: Check out the codebase - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - - name: Set up QEMU - uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 - - - name: Configure AWS credentials - if: ${{ github.event_name != 'pull_request' }} - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - aws-region: ${{ secrets.AWS_REGION }} - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - - - name: Login to Amazon ECR Public Gallery - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: public.ecr.aws - - - name: Login to Docker Hub - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Login to GitHub Container Registry - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Login to Quay - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: quay.io - username: ${{ secrets.QUAY_USERNAME }} - password: ${{ secrets.QUAY_TOKEN }} - - - name: Extract metadata (annotations, labels, tags) for Docker - id: meta - uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 - with: - images: | - docker.io/nginxinc/nginx-unprivileged - ghcr.io/nginxinc/nginx-unprivileged - public.ecr.aws/nginx/nginx-unprivileged - quay.io/nginx/nginx-unprivileged - tags: | - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }} - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }} - type=raw,value=${{ needs.version.outputs.major }}-alpine - type=raw,value=${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }} - type=raw,value=mainline-alpine - type=raw,value=mainline-alpine${{ needs.version.outputs.distro }} - type=raw,value=alpine - type=raw,value=alpine${{ needs.version.outputs.distro }} - env: - DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - - - name: Build and push NGINX mainline Alpine image to Amazon ECR Public Gallery, Docker Hub, GitHub Container Registry, and Quay - id: build - uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 + - name: Upload artifact + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x - context: "{{ defaultContext }}:mainline/alpine" - labels: ${{ steps.meta.outputs.labels }} - annotations: ${{ steps.meta.outputs.annotations }} - tags: ${{ steps.meta.outputs.tags }} - push: ${{ github.event_name != 'pull_request' }} - # cache-from: type=gha,scope=debian-perl - # cache-to: type=gha,mode=min,scope=debian-perl - - - name: Sign Docker Hub Manifest - if: ${{ github.event_name != 'pull_request' }} - run: | - set -ex - sudo apt update - sudo apt install -y notary - mkdir -p ~/.docker/trust/private - echo "$DOCKER_CONTENT_TRUST_REPOSITORY_KEY" > ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key - chmod 0400 ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key - docker trust key load ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key --name nginx - DIGEST=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".digest' | cut -d ':' -f2) - SIZE=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".size') - export NOTARY_AUTH=$(printf "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64 -w0) - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose - env: - DOCKER_CONTENT_TRUST_REPOSITORY_KEY: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY }} - DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID }} - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - NOTARY_TARGETS_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - - perl: - name: Build Alpine NGINX mainline perl Docker image - needs: [version, core] + name: alpine-slim-${{ matrix.platform }} + path: ${{ runner.temp }}/alpine-slim-${{ matrix.platform }}.tar + if-no-files-found: error + retention-days: 1 + # - name: Save image as tarball + # run: | + # mkdir -p ${{ runner.temp }}/images + # docker save ghcr.io/nginxinc/nginx-unprivileged:temp-${{ matrix.platform }} -o ${{ runner.temp }}/images/nginx-unprivileged-${{ matrix.platform }}.tar + + # - name: Export digest + # run: | + # mkdir -p ${{ runner.temp }}/digests + # digest="${{ steps.build.outputs.digest }}" + # touch "${{ runner.temp }}/digests/${digest#sha256:}" + + # - name: Prepare env + # run: | + # platform=${{ matrix.platform }} + # echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + # - name: Upload digest + # uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + # with: + # name: digests-${{ env.PLATFORM_PAIR }} + # path: ${{ runner.temp }}/digests/* + # if-no-files-found: error + # retention-days: 1 + # - name: Export digest + # run: | + # mkdir -p ${{ runner.temp }}/digests + # digest="${{ steps.build.outputs.digest }}" + # touch "${{ runner.temp }}/digests/${digest#sha256:}" + + # - name: Prepare env + # run: | + # platform=${{ matrix.platform }} + # echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + + # - name: Upload digest + # uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 + # with: + # name: digests-${{ env.PLATFORM_PAIR }} + # path: ${{ runner.temp }}/digests/* + # if-no-files-found: error + # retention-days: 1 + + merge-slim: runs-on: ubuntu-24.04 - strategy: - fail-fast: false + needs: [slim, version] steps: - - name: Check out the codebase - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - name: Download image tarballs + uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + with: + name: images-* + path: /tmp/images + merge-multiple: true - - name: Set up QEMU - uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0 + # - name: Download digests + # uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 + # with: + # pattern: digests-* + # path: /tmp/digests + # merge-multiple: true - name: Set up Docker Buildx uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 - - name: Configure AWS credentials - if: ${{ github.event_name != 'pull_request' }} - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 - with: - aws-region: ${{ secrets.AWS_REGION }} - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - - - name: Login to Amazon ECR Public Gallery - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: public.ecr.aws - - - name: Login to Docker Hub - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Load images + run: | + for tar in /tmp/images/*.tar; do + docker load -i $tar + done + docker image ls -a + + # - name: Login to Docker Hub + # # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # username: ${{ secrets.DOCKERHUB_USERNAME }} + # password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Login to GitHub Container Registry - if: ${{ github.event_name != 'pull_request' }} + # if: ${{ github.event_name != 'pull_request' }} uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Login to Quay - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 - with: - registry: quay.io - username: ${{ secrets.QUAY_USERNAME }} - password: ${{ secrets.QUAY_TOKEN }} - - name: Extract metadata (annotations, labels, tags) for Docker id: meta uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 with: images: | - docker.io/nginxinc/nginx-unprivileged ghcr.io/nginxinc/nginx-unprivileged - public.ecr.aws/nginx/nginx-unprivileged - quay.io/nginx/nginx-unprivileged + # docker.io/nginxinc/nginx-unprivileged tags: | - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-perl - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-perl - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-perl - type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-perl - type=raw,value=${{ needs.version.outputs.major }}-alpine-perl - type=raw,value=${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-perl - type=raw,value=mainline-alpine-perl - type=raw,value=mainline-alpine${{ needs.version.outputs.distro }}-perl - type=raw,value=alpine-perl - type=raw,value=alpine${{ needs.version.outputs.distro }}-perl + type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-slim-test + type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-slim-test + type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-slim-test + type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-slim-test + type=raw,value=${{ needs.version.outputs.major }}-alpine-slim-test + type=raw,value=${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-slim-test + type=raw,value=mainline-alpine-slim-test + type=raw,value=mainline-alpine${{ needs.version.outputs.distro }}-slim-test + type=raw,value=alpine-slim-test + type=raw,value=alpine${{ needs.version.outputs.distro }}-slim-test env: - DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + DOCKER_METADATA_ANNOTATIONS_LEVELS: index - - name: Build and push NGINX mainline perl Alpine image to Amazon ECR Public Gallery, Docker Hub, GitHub Container Registry, and Quay - id: build - uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 - with: - platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x - context: "{{ defaultContext }}:mainline/alpine-perl" - labels: ${{ steps.meta.outputs.labels }} - annotations: ${{ steps.meta.outputs.annotations }} - tags: ${{ steps.meta.outputs.tags }} - push: ${{ github.event_name != 'pull_request' }} - # cache-from: type=gha,scope=alpine-perl - # cache-to: type=gha,mode=min,scope=alpine-perl + - name: Create manifest list and push + working-directory: /tmp/digests + run: | + set -x + annotations=$(jq -cr '.annotations | map((split("=")[0] + "=\"" + split("=")[1] + "\"") | "--annotation " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") + tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") + eval "docker buildx imagetools create $annotations $tags $(for tar in /tmp/images/*.tar; do echo 'ghcr.io/nginxinc/nginx-unprivileged:temp-${tar##*/}'; done)" - - name: Sign Docker Hub Manifest - if: ${{ github.event_name != 'pull_request' }} + - name: Inspect image run: | - set -ex - sudo apt update - sudo apt install -y notary - mkdir -p ~/.docker/trust/private - echo "$DOCKER_CONTENT_TRUST_REPOSITORY_KEY" > ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key - chmod 0400 ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key - docker trust key load ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key --name nginx - DIGEST=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".digest' | cut -d ':' -f2) - SIZE=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".size') - export NOTARY_AUTH=$(printf "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64 -w0) - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine-perl $SIZE --sha256 $DIGEST --publish --verbose - notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose - env: - DOCKER_CONTENT_TRUST_REPOSITORY_KEY: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY }} - DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID }} - DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} - NOTARY_TARGETS_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} + docker buildx imagetools inspect ghcr.io/nginxinc/nginx-unprivileged:alpine-slim-test + docker buildx imagetools inspect docker.io/nginxinc/nginx-unprivileged:alpine-slim-test + + # - name: Sign Docker Hub Manifest + # if: ${{ github.event_name != 'pull_request' }} + # run: | + # set -ex + # sudo apt update + # sudo apt install -y notary + # mkdir -p ~/.docker/trust/private + # echo "$DOCKER_CONTENT_TRUST_REPOSITORY_KEY" > ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key + # chmod 0400 ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key + # docker trust key load ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key --name nginx + # DIGEST=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".digest' | cut -d ':' -f2) + # SIZE=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".size') + # export NOTARY_AUTH=$(printf "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64 -w0) + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine-slim $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine${{ needs.version.outputs.distro }}-slim $SIZE --sha256 $DIGEST --publish --verbose + # env: + # DOCKER_CONTENT_TRUST_REPOSITORY_KEY: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY }} + # DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID }} + # DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} + # NOTARY_TARGETS_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} + + # core: + # name: Build Alpine NGINX mainline Docker image + # needs: [version, slim] + # runs-on: ubuntu-24.04 + # strategy: + # fail-fast: false + # steps: + # - name: Check out the codebase + # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # - name: Set up QEMU + # uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0 + + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + + # - name: Configure AWS credentials + # if: ${{ github.event_name != 'pull_request' }} + # uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + # with: + # aws-region: ${{ secrets.AWS_REGION }} + # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + # aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + # - name: Login to Amazon ECR Public Gallery + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: public.ecr.aws + + # - name: Login to Docker Hub + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # username: ${{ secrets.DOCKERHUB_USERNAME }} + # password: ${{ secrets.DOCKERHUB_TOKEN }} + + # - name: Login to GitHub Container Registry + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: ghcr.io + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Login to Quay + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: quay.io + # username: ${{ secrets.QUAY_USERNAME }} + # password: ${{ secrets.QUAY_TOKEN }} + + # - name: Extract metadata (annotations, labels, tags) for Docker + # id: meta + # uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 + # with: + # images: | + # docker.io/nginxinc/nginx-unprivileged + # ghcr.io/nginxinc/nginx-unprivileged + # public.ecr.aws/nginx/nginx-unprivileged + # quay.io/nginx/nginx-unprivileged + # tags: | + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }} + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }} + # type=raw,value=${{ needs.version.outputs.major }}-alpine + # type=raw,value=${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }} + # type=raw,value=mainline-alpine + # type=raw,value=mainline-alpine${{ needs.version.outputs.distro }} + # type=raw,value=alpine + # type=raw,value=alpine${{ needs.version.outputs.distro }} + # env: + # DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + + # - name: Build and push NGINX mainline Alpine image to Amazon ECR Public Gallery, Docker Hub, GitHub Container Registry, and Quay + # id: build + # uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 + # with: + # platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x + # context: "{{ defaultContext }}:mainline/alpine" + # labels: ${{ steps.meta.outputs.labels }} + # annotations: ${{ steps.meta.outputs.annotations }} + # tags: ${{ steps.meta.outputs.tags }} + # push: ${{ github.event_name != 'pull_request' }} + # # cache-from: type=gha,scope=debian-perl + # # cache-to: type=gha,mode=min,scope=debian-perl + + # - name: Sign Docker Hub Manifest + # if: ${{ github.event_name != 'pull_request' }} + # run: | + # set -ex + # sudo apt update + # sudo apt install -y notary + # mkdir -p ~/.docker/trust/private + # echo "$DOCKER_CONTENT_TRUST_REPOSITORY_KEY" > ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key + # chmod 0400 ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key + # docker trust key load ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key --name nginx + # DIGEST=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".digest' | cut -d ':' -f2) + # SIZE=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".size') + # export NOTARY_AUTH=$(printf "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64 -w0) + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine${{ needs.version.outputs.distro }} $SIZE --sha256 $DIGEST --publish --verbose + # env: + # DOCKER_CONTENT_TRUST_REPOSITORY_KEY: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY }} + # DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID }} + # DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} + # NOTARY_TARGETS_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} + + # perl: + # name: Build Alpine NGINX mainline perl Docker image + # needs: [version, core] + # runs-on: ubuntu-24.04 + # strategy: + # fail-fast: false + # steps: + # - name: Check out the codebase + # uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + # - name: Set up QEMU + # uses: docker/setup-qemu-action@53851d14592bedcffcf25ea515637cff71ef929a # v3.3.0 + + # - name: Set up Docker Buildx + # uses: docker/setup-buildx-action@6524bf65af31da8d45b59e8c27de4bd072b392f5 # v3.8.0 + + # - name: Configure AWS credentials + # if: ${{ github.event_name != 'pull_request' }} + # uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502 # v4.0.2 + # with: + # aws-region: ${{ secrets.AWS_REGION }} + # aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + # aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + + # - name: Login to Amazon ECR Public Gallery + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: public.ecr.aws + + # - name: Login to Docker Hub + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # username: ${{ secrets.DOCKERHUB_USERNAME }} + # password: ${{ secrets.DOCKERHUB_TOKEN }} + + # - name: Login to GitHub Container Registry + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: ghcr.io + # username: ${{ github.actor }} + # password: ${{ secrets.GITHUB_TOKEN }} + + # - name: Login to Quay + # if: ${{ github.event_name != 'pull_request' }} + # uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0 + # with: + # registry: quay.io + # username: ${{ secrets.QUAY_USERNAME }} + # password: ${{ secrets.QUAY_TOKEN }} + + # - name: Extract metadata (annotations, labels, tags) for Docker + # id: meta + # uses: docker/metadata-action@369eb591f429131d6889c46b94e711f089e6ca96 # v5.6.1 + # with: + # images: | + # docker.io/nginxinc/nginx-unprivileged + # ghcr.io/nginxinc/nginx-unprivileged + # public.ecr.aws/nginx/nginx-unprivileged + # quay.io/nginx/nginx-unprivileged + # tags: | + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-perl + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-perl + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-perl + # type=raw,value=${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-perl + # type=raw,value=${{ needs.version.outputs.major }}-alpine-perl + # type=raw,value=${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-perl + # type=raw,value=mainline-alpine-perl + # type=raw,value=mainline-alpine${{ needs.version.outputs.distro }}-perl + # type=raw,value=alpine-perl + # type=raw,value=alpine${{ needs.version.outputs.distro }}-perl + # env: + # DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + + # - name: Build and push NGINX mainline perl Alpine image to Amazon ECR Public Gallery, Docker Hub, GitHub Container Registry, and Quay + # id: build + # uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 + # with: + # platforms: linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64, linux/386, linux/ppc64le, linux/riscv64, linux/s390x + # context: "{{ defaultContext }}:mainline/alpine-perl" + # labels: ${{ steps.meta.outputs.labels }} + # annotations: ${{ steps.meta.outputs.annotations }} + # tags: ${{ steps.meta.outputs.tags }} + # push: ${{ github.event_name != 'pull_request' }} + # # cache-from: type=gha,scope=alpine-perl + # # cache-to: type=gha,mode=min,scope=alpine-perl + + # - name: Sign Docker Hub Manifest + # if: ${{ github.event_name != 'pull_request' }} + # run: | + # set -ex + # sudo apt update + # sudo apt install -y notary + # mkdir -p ~/.docker/trust/private + # echo "$DOCKER_CONTENT_TRUST_REPOSITORY_KEY" > ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key + # chmod 0400 ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key + # docker trust key load ~/.docker/trust/private/$DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID.key --name nginx + # DIGEST=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".digest' | cut -d ':' -f2) + # SIZE=$(printf '${{ steps.build.outputs.metadata }}' | jq -r '."containerimage.descriptor".size') + # export NOTARY_AUTH=$(printf "${{ secrets.DOCKERHUB_USERNAME }}:${{ secrets.DOCKERHUB_TOKEN }}" | base64 -w0) + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}.${{ needs.version.outputs.patch }}-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}.${{ needs.version.outputs.minor }}-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged ${{ needs.version.outputs.major }}-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged mainline-alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine-perl $SIZE --sha256 $DIGEST --publish --verbose + # notary -d ~/.docker/trust/ -s https://notary.docker.io addhash docker.io/nginxinc/nginx-unprivileged alpine${{ needs.version.outputs.distro }}-perl $SIZE --sha256 $DIGEST --publish --verbose + # env: + # DOCKER_CONTENT_TRUST_REPOSITORY_KEY: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY }} + # DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_KEY_ID }} + # DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} + # NOTARY_TARGETS_PASSPHRASE: ${{ secrets.DOCKER_CONTENT_TRUST_REPOSITORY_PASSPHRASE }} From 33460e69221bc979e24b93c396a0cbdb9631b5e9 Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia <alessfg@hotmail.com> Date: Wed, 15 Jan 2025 21:24:09 +0100 Subject: [PATCH 2/7] Update alpine-mainline.yml --- .github/workflows/alpine-mainline.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/alpine-mainline.yml b/.github/workflows/alpine-mainline.yml index b676d17..684f213 100644 --- a/.github/workflows/alpine-mainline.yml +++ b/.github/workflows/alpine-mainline.yml @@ -108,6 +108,11 @@ jobs: # env: # DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + - name: Prepare env + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + - name: Build and push NGINX mainline slim Alpine image to Amazon ECR Public Gallery, Docker Hub, GitHub Container Registry, and Quay id: build uses: docker/build-push-action@b32b51a8eda65d6793cd0494a773d4f6bcef32dc # v6.11.0 @@ -118,7 +123,7 @@ jobs: annotations: ${{ steps.meta.outputs.annotations }} # outputs: type=image,"name=ghcr.io/nginxinc/nginx-unprivileged,docker.io/nginxinc/nginx-unprivileged",push-by-digest=true,name-canonical=true,push=true # outputs: type=image,"name=ghcr.io/nginxinc/nginx-unprivileged,docker.io/nginxinc/nginx-unprivileged",push-by-digest=true,name-canonical=true,push=true - outputs: type=docker,dest=${{ runner.temp }}/alpine-slim-${{ matrix.platform }}.tar + outputs: type=docker,dest=${{ runner.temp }}/alpine-slim-${{ env.PLATFORM_PAIR }}.tar # tags: ${{ steps.meta.outputs.tags }} # push: false # push: ${{ github.event_name != 'pull_request' }} @@ -128,10 +133,11 @@ jobs: - name: Upload artifact uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 with: - name: alpine-slim-${{ matrix.platform }} - path: ${{ runner.temp }}/alpine-slim-${{ matrix.platform }}.tar + name: alpine-slim-${{ env.PLATFORM_PAIR }} + path: ${{ runner.temp }}/alpine-slim-${{ env.PLATFORM_PAIR }}.tar if-no-files-found: error retention-days: 1 + # - name: Save image as tarball # run: | # mkdir -p ${{ runner.temp }}/images @@ -161,10 +167,7 @@ jobs: # digest="${{ steps.build.outputs.digest }}" # touch "${{ runner.temp }}/digests/${digest#sha256:}" - # - name: Prepare env - # run: | - # platform=${{ matrix.platform }} - # echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + # - name: Upload digest # uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4.6.0 From 6fd496ca41d81a8c94c78eaa06151c18402d4dc7 Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia <alessfg@hotmail.com> Date: Wed, 15 Jan 2025 21:54:20 +0100 Subject: [PATCH 3/7] Update alpine-mainline.yml --- .github/workflows/alpine-mainline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alpine-mainline.yml b/.github/workflows/alpine-mainline.yml index 684f213..3bbbce8 100644 --- a/.github/workflows/alpine-mainline.yml +++ b/.github/workflows/alpine-mainline.yml @@ -184,7 +184,7 @@ jobs: - name: Download image tarballs uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: - name: images-* + name: alpine-slim-* path: /tmp/images merge-multiple: true From eb9cb91a6e208f1a5ebe46dc6effe8931b2e7b6f Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia <alessfg@hotmail.com> Date: Wed, 15 Jan 2025 22:18:01 +0100 Subject: [PATCH 4/7] Update alpine-mainline.yml --- .github/workflows/alpine-mainline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/alpine-mainline.yml b/.github/workflows/alpine-mainline.yml index 3bbbce8..fecbbc7 100644 --- a/.github/workflows/alpine-mainline.yml +++ b/.github/workflows/alpine-mainline.yml @@ -184,8 +184,8 @@ jobs: - name: Download image tarballs uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8 with: - name: alpine-slim-* path: /tmp/images + pattern: alpine-slim-* merge-multiple: true # - name: Download digests @@ -252,7 +252,7 @@ jobs: - name: Inspect image run: | docker buildx imagetools inspect ghcr.io/nginxinc/nginx-unprivileged:alpine-slim-test - docker buildx imagetools inspect docker.io/nginxinc/nginx-unprivileged:alpine-slim-test + # docker buildx imagetools inspect docker.io/nginxinc/nginx-unprivileged:alpine-slim-test # - name: Sign Docker Hub Manifest # if: ${{ github.event_name != 'pull_request' }} From abff974fa4c79f7eceee132e94491e8bf8ad3ef6 Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia <alessfg@hotmail.com> Date: Wed, 15 Jan 2025 22:37:46 +0100 Subject: [PATCH 5/7] Update alpine-mainline.yml --- .github/workflows/alpine-mainline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/alpine-mainline.yml b/.github/workflows/alpine-mainline.yml index fecbbc7..a675e81 100644 --- a/.github/workflows/alpine-mainline.yml +++ b/.github/workflows/alpine-mainline.yml @@ -242,7 +242,7 @@ jobs: DOCKER_METADATA_ANNOTATIONS_LEVELS: index - name: Create manifest list and push - working-directory: /tmp/digests + working-directory: /tmp/images run: | set -x annotations=$(jq -cr '.annotations | map((split("=")[0] + "=\"" + split("=")[1] + "\"") | "--annotation " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") From 6c463cd3e87e64f168ed7e3d551654f00ae85476 Mon Sep 17 00:00:00 2001 From: Alessandro Fael Garcia <alessfg@hotmail.com> Date: Wed, 15 Jan 2025 23:00:06 +0100 Subject: [PATCH 6/7] Update alpine-mainline.yml --- .github/workflows/alpine-mainline.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/alpine-mainline.yml b/.github/workflows/alpine-mainline.yml index a675e81..f723adf 100644 --- a/.github/workflows/alpine-mainline.yml +++ b/.github/workflows/alpine-mainline.yml @@ -247,7 +247,8 @@ jobs: set -x annotations=$(jq -cr '.annotations | map((split("=")[0] + "=\"" + split("=")[1] + "\"") | "--annotation " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") tags=$(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") - eval "docker buildx imagetools create $annotations $tags $(for tar in /tmp/images/*.tar; do echo 'ghcr.io/nginxinc/nginx-unprivileged:temp-${tar##*/}'; done)" + images=$(for tar in /tmp/images/*.tar; do echo "ghcr.io/nginxinc/nginx-unprivileged:temp-${tar##*/}"; done) + eval "docker buildx imagetools create $annotations $tags $images" - name: Inspect image run: | From 5f08369184383e5f39d9dafc22053e1a5a5ab119 Mon Sep 17 00:00:00 2001 From: Dylen Turnbull <37633141+DylenTurnbull@users.noreply.github.com> Date: Tue, 25 Mar 2025 07:17:45 -0700 Subject: [PATCH 7/7] docs: Update community files Co-Authored-By: Alessandro Fael Garcia <alessfg@hotmail.com> --- .github/CODEOWNERS | 5 ++ .github/ISSUE_TEMPLATE/bug_report.md | 32 ---------- .github/ISSUE_TEMPLATE/bug_report.yml | 62 ++++++++++++++++++ .github/ISSUE_TEMPLATE/config.yml | 12 ++++ .github/ISSUE_TEMPLATE/feature_request.md | 22 ------- .github/ISSUE_TEMPLATE/feature_request.yml | 41 ++++++++++++ .github/ISSUE_TEMPLATE/security_report.md | 27 -------- .github/pull_request_template.md | 9 +-- .github/scorecard.yml | 7 ++ .github/workflows/f5_cla.yml | 42 ++++++++++++ .github/workflows/ossf_scorecard.yml | 52 +++++++++++++++ CODE_OF_CONDUCT.md | 21 +++--- CONTRIBUTING.md | 74 ++++++++++------------ README.md | 39 ++++++------ SECURITY.md | 24 +++---- SUPPORT.md | 20 +++--- 16 files changed, 310 insertions(+), 179 deletions(-) create mode 100644 .github/CODEOWNERS delete mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml delete mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.yml delete mode 100644 .github/ISSUE_TEMPLATE/security_report.md create mode 100644 .github/scorecard.yml create mode 100644 .github/workflows/f5_cla.yml create mode 100644 .github/workflows/ossf_scorecard.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..268b223 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +##################### +# Main global owner # +##################### + +* diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index d67363b..0000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -name: Bug report -about: Create a bug report to help us improve -title: "" -labels: "" -assignees: "" ---- -### Describe the bug - -A clear and concise description of what the bug is. - -### To reproduce - -Steps to reproduce the behavior: - -1. Deploy NGINX Unprivileged Docker image -2. View output/logs/configuration on '...' -3. See error - -### Expected behavior - -A clear and concise description of what you expected to happen. - -### Your environment - -- Version of Docker and method of installation (e.g. Docker Desktop / Docker Server) -- Version/tag of the NGINX Unprivileged Docker image (e.g. `nginxinc/nginx-unprivileged:alpine`) -- Target deployment environment/platform (e.g. OpenShift / Kubernetes / Docker Compose / etc...) - -### Additional context - -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 0000000..fec21fc --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,62 @@ +--- +name: ๐ Bug report +description: Create a report to help us improve +labels: bug +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this bug report! + + Before you continue filling out this report, please take a moment to check that your bug has not been [already reported on GitHub][issue search] ๐ + + Remember to redact any sensitive information such as authentication credentials and/or license keys! + + [issue search]: ../search?q=is%3Aissue&type=issues + + - type: textarea + id: overview + attributes: + label: Bug Overview + description: A clear and concise overview of the bug. + placeholder: When I do "X" with the NGINX unprivileged Docker image, "Y" happens instead of "Z". + validations: + required: true + + - type: textarea + id: behavior + attributes: + label: Expected Behavior + description: A clear and concise description of what you expected to happen. + placeholder: When I do "X" with the NGINX unprivileged Docker image, I expect "Z" to happen. + validations: + required: true + + - type: textarea + id: steps + attributes: + label: Steps to Reproduce the Bug + description: Detail the series of steps required to reproduce the bug. Deploy NGINX Unprivileged Docker image, View output/logs/configuration on '...', See error. + placeholder: When I run the NGINX Docker unprivileged image using [...], the image fails with an error message. If I check the terminal outputs and/or logs, I see the following error info. + validations: + required: true + + - type: textarea + id: environment + attributes: + label: Environment Details + description: Please provide details about your environment. + value: | + - Version of Docker and method of installation: [e.g. Docker Desktop / Docker Server] + - Version/tag of the NGINX Docker unprivileged image or specific commit: [e.g. 1.4.3/commit hash] + - Target deployment platform: [e.g. OpenShift/Kubernetes/Docker Compose/local cluster/etc...] + - Target OS: [e.g. RHEL 9/Ubuntu 24.04/etc...] + validations: + required: true + + - type: textarea + id: context + attributes: + label: Additional Context + description: Add any other context about the problem here. + placeholder: Feel free to add any other context/information/screenshots/etc... that you think might be relevant to this issue in here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..3f7850f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,12 @@ +--- +blank_issues_enabled: false +contact_links: + - name: ๐ฌ Talk to the NGINX community! + url: https://community.nginx.org + about: A community forum for NGINX users, developers, and contributors + - name: ๐ Code of Conduct + url: https://www.contributor-covenant.org/version/2/1/code_of_conduct + about: NGINX follows the Contributor Covenant Code of Conduct to ensure a safe and inclusive community + - name: ๐ผ For commercial & enterprise users + url: https://www.f5.com/products/nginx + about: F5 offers a wide range of NGINX products for commercial & enterprise users diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bb6fb0f..0000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: "" -labels: "" -assignees: "" ---- -### Is your feature request related to a problem? Please describe - -A clear and concise description of what the problem is. Ex. I'm always frustrated when ... - -### Describe the solution you'd like - -A clear and concise description of what you want to happen. - -### Describe alternatives you've considered - -A clear and concise description of any alternative solutions or features you've considered. - -### Additional context - -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 0000000..b1a3fcb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,41 @@ +--- +name: โจ Feature request +description: Suggest an idea for this project +labels: enhancement +body: + - type: markdown + attributes: + value: | + Thanks for taking the time to fill out this feature request! + + Before you continue filling out this request, please take a moment to check that your feature has not been [already requested on GitHub][issue search] ๐ + + **Note:** If you are seeking community support or have a question, please consider starting a new thread via [GitHub discussions][discussions] or the [NGINX Community forum][forum]. + + [issue search]: ../search?q=is%3Aissue&type=issues + + [discussions]: ../discussions + [forum]: https://community.nginx.org + + - type: textarea + id: overview + attributes: + label: Feature Overview + description: A clear and concise description of what the feature request is. + placeholder: I would like the NGINX Docker unprivileged image to be able to do "X". + validations: + required: true + + - type: textarea + id: alternatives + attributes: + label: Alternatives Considered + description: Detail any potential alternative solutions/workarounds you've used or considered. + placeholder: I have done/might be able to do "X" using the NGINX Docker unprivileged image by doing "Y". + + - type: textarea + id: context + attributes: + label: Additional Context + description: Add any other context about the problem here. + placeholder: Feel free to add any other context/information/screenshots/etc... that you think might be relevant to this feature request here. diff --git a/.github/ISSUE_TEMPLATE/security_report.md b/.github/ISSUE_TEMPLATE/security_report.md deleted file mode 100644 index 0e79284..0000000 --- a/.github/ISSUE_TEMPLATE/security_report.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -name: Security report -about: Create a security report to help us improve -title: "" -labels: "" -assignees: "" ---- -### Describe the bug - -A clear and concise description of what the security vulnerability is. - -### To reproduce - -Steps to reproduce the behavior: - -1. Deploy NGINX Unprivileged Docker image -2. View output/logs/configuration on '...' -3. See error - -### Your environment - -- Version of the NGINX Unprivileged Docker image -- Target deployment environment/platform - -### Additional context - -Does this security vulnerability relate to one of the NGINX libraries specified in the [`SECURITY`](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/SECURITY.md) doc? diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index a054d33..87a9619 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,7 +6,8 @@ Describe the use case and detail of the change. If this PR addresses an issue on Before creating a PR, run through this checklist and mark each as complete: -- [ ] I have read the [`CONTRIBUTING`](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/CONTRIBUTING.md) document -- [ ] I have run `./update.sh` and ensured all entrypoint/Dockerfile template changes have been applied to the relevant image entrypoint scripts & Dockerfiles -- [ ] I have tested that the NGINX Unprivileged Docker images build and run correctly on all supported architectures on an unprivileged environment (check out the [`README`](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/README.md) for more details) -- [ ] I have updated any relevant documentation ([`README`](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/README.md)) +- [ ] I have read the [contributing guidelines](/CONTRIBUTING.md) +- [ ] I have signed the [F5 Contributor License Agreement (CLA)](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md) +- [ ] I have run the [`update.sh`](/update.sh) script and ensured all entrypoint/Dockerfile template changes have been applied to the relevant image entrypoint scripts & Dockerfiles +- [ ] I have tested that the NGINX Docker unprivileged image builds and runs correctly on all supported architectures on an unprivileged environment (check out the [`README`](/README.md) for more details) +- [ ] I have updated any relevant documentation ([`README.md`](/README.md)) diff --git a/.github/scorecard.yml b/.github/scorecard.yml new file mode 100644 index 0000000..3bae359 --- /dev/null +++ b/.github/scorecard.yml @@ -0,0 +1,7 @@ +--- +annotations: + - checks: + - fuzzing + - sast + reasons: + - reason: not-applicable diff --git a/.github/workflows/f5_cla.yml b/.github/workflows/f5_cla.yml new file mode 100644 index 0000000..fd93801 --- /dev/null +++ b/.github/workflows/f5_cla.yml @@ -0,0 +1,42 @@ +--- +name: F5 CLA +on: + issue_comment: + types: [created] + pull_request_target: + types: [opened, closed, synchronize] +permissions: read-all +jobs: + f5-cla: + name: F5 CLA + runs-on: ubuntu-24.04 + permissions: + actions: write + pull-requests: write + statuses: write + steps: + - name: Run F5 Contributor License Agreement (CLA) assistant + if: (github.event.comment.body == 'recheck' || github.event.comment.body == 'I have hereby read the F5 CLA and agree to its terms') || github.event_name == 'pull_request_target' + uses: contributor-assistant/github-action@ca4a40a7d1004f18d9960b404b97e5f30a505a08 # v2.6.1 + with: + # Any pull request targeting the following branch will trigger a CLA check. + # NOTE: You might need to edit this value to 'master'. + branch: main + # Path to the CLA document. + path-to-document: https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md + # Custom CLA messages. + custom-notsigned-prcomment: '๐ Thank you for your contribution! It appears you have not yet signed the [F5 Contributor License Agreement (CLA)](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md), which is required for your changes to be incorporated into an F5 Open Source Software (OSS) project. Please kindly read the [F5 CLA](https://github.com/f5/f5-cla/blob/main/docs/f5_cla.md) and reply on a new comment with the following text to agree:' + custom-pr-sign-comment: 'I have hereby read the F5 CLA and agree to its terms' + custom-allsigned-prcomment: 'โ All required contributors have signed the F5 CLA for this PR. Thank you!' + # Remote repository storing CLA signatures. + remote-organization-name: f5 + remote-repository-name: f5-cla-data + path-to-signatures: signatures/signatures.json + # Comma separated list of usernames for maintainers or any other individuals who should not be prompted for a CLA. + # NOTE: You will want to edit the usernames to suit your project needs. + allowlist: bot* + # Do not lock PRs after a merge. + lock-pullrequest-aftermerge: false + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + PERSONAL_ACCESS_TOKEN: ${{ secrets.F5_CLA_TOKEN }} diff --git a/.github/workflows/ossf_scorecard.yml b/.github/workflows/ossf_scorecard.yml new file mode 100644 index 0000000..21d114a --- /dev/null +++ b/.github/workflows/ossf_scorecard.yml @@ -0,0 +1,52 @@ +--- +# This workflow uses actions that are not certified by GitHub. They are provided by a third-party and are governed by separate terms of service, privacy policy, and support documentation. +name: OSSF Scorecard +on: + # For Branch-Protection check. Only the default branch is supported. See https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection. + branch_protection_rule: + # To guarantee Maintained check is occasionally updated. See https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained. + schedule: + - cron: "0 0 * * 1" + push: + branches: [main] + workflow_dispatch: +# Declare default permissions as read only. +permissions: read-all +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-24.04 + # Delete the conditional below if you are using the OSSF Scorecard on a private repository. + if: ${{ github.event.repository.private == false }} + permissions: + # Needed if using Code Scanning alerts. + security-events: write + # Needed for GitHub OIDC token if publish_results is true. + id-token: write + steps: + - name: Check out the codebase + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Run analysis + uses: ossf/scorecard-action@f49aabe0b5af0936a0987cfb85d86b75731b0186 # v2.4.1 + with: + results_file: results.sarif + results_format: sarif + # Publish the results for public repositories to enable scorecard badges. For more details, see https://github.com/ossf/scorecard-action#publishing-results. + publish_results: true + + # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF format to the repository Actions tab. + - name: Upload artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + + # Upload the results to GitHub's code scanning dashboard. + - name: Upload SARIF results to code scanning + uses: github/codeql-action/upload-sarif@5f8171a638ada777af81d42b55959a643bb29017 # v3.28.12 + with: + sarif_file: results.sarif diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 0c6130c..e18d370 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -10,20 +10,19 @@ We pledge to act and interact in ways that contribute to an open, welcoming, div Examples of behavior that contributes to a positive environment for our community include: -- Demonstrating empathy and kindness toward other people -- Being respectful of differing opinions, viewpoints, and experiences -- Giving and gracefully accepting constructive feedback -- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience -- Focusing on what is best not just for us as individuals, but for the overall community +- Demonstrating empathy and kindness toward other people. +- Being respectful of differing opinions, viewpoints, and experiences. +- Giving and gracefully accepting constructive feedback. +- Accepting responsibility and apologizing to those affected by our mistakes, and learning from the experience. +- Focusing on what is best not just for us as individuals, but for the overall community. Examples of unacceptable behavior include: -- The use of sexualized language or imagery, and sexual attention or advances of - any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Publishing others' private information, such as a physical or email address, without their explicit permission -- Other conduct which could reasonably be considered inappropriate in a professional setting +- The use of sexualized language or imagery, and sexual attention or advances of any kind. +- Trolling, insulting or derogatory comments, and personal or political attacks. +- Public or private harassment. +- Publishing others' private information, such as a physical or email address, without their explicit permission. +- Other conduct which could reasonably be considered inappropriate in a professional setting. ## Enforcement Responsibilities diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 8b4d720..38f28e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,67 +1,59 @@ # Contributing Guidelines -The following is a set of guidelines for contributing to the Docker Unprivileged NGINX image. We really appreciate that you are considering contributing! +The following is a set of guidelines for contributing to the NGINX Docker unprivileged image. We really appreciate that you are considering contributing! #### Table Of Contents -[Ask a Question](#ask-a-question) +- [Getting Started](#getting-started) +- [Contributing](#contributing) +- [Code Guidelines](#code-guidelines) -[Project Overview](#project-overview) +## Getting Started -[Contributing](#contributing) - -[Code Guidelines](#code-guidelines) - -* [Docker NGINX Unprivileged Guidelines](#docker-nginx-unprivileged-guidelines) -* [Git Guidelines](#git-guidelines) - -[Code of Conduct](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/CODE_OF_CONDUCT.md) - -## Ask a Question - -Don't know how something works? Curious if the role can achieve your desired functionality? Please open an Issue on GitHub with the label `question`. - -### Project Overview - -* The Docker Unprivileged NGINX repository is a mirror image of the [Docker NGINX image](https://github.com/nginxinc/docker-nginx). Changes have been made in order to support running NGINX in an unprivileged environment. -* New Docker Unprivileged NGINX images are built on a weekly basis using GitHub actions. +Look at the upstream Docker image [how to use this image guide](https://hub.docker.com/_/nginx/) to get the NGINX Docker unprivileged image up and running. ## Contributing ### Report a Bug -To report a bug, open an issue on GitHub with the label `bug` using the available bug report issue template. Please ensure the issue has not already been reported. +To report a bug, open an issue on GitHub with the label `bug` using the available [bug report issue form](/.github/ISSUE_TEMPLATE/bug_report.yml). Please ensure the bug has not already been reported. **If the bug is a potential security vulnerability, please report it using our [security policy](/SECURITY.md).** -### Report a Security vulnerability +### Suggest a Feature or Enhancement -To report a security vulnerability, open an issue on GitHub with the label `security` using the available security report issue template. Please ensure the security vulnerability directly impacts one of the NGINX dependencies listed in the [`SECURITY`](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/SECURITY.md) doc. Other security vulnerabilities should be addressed by the weekly Monday night build and as such will be promptly closed. +To suggest a feature or enhancement, please create an issue on GitHub with the label `enhancement` using the available [feature request issue form](/.github/ISSUE_TEMPLATE/feature_request.yml). Please ensure the feature or enhancement has not already been suggested. -### Suggest a Feature or Enhancement +### Open a Pull Request (PR) -To suggest an enhancement, please create an issue on GitHub with the label `feature` or `enhancement` using the available feature issue template. +- Fork the repo, create a branch, implement your changes, test that the corresponding Docker images can be built and run as intended, and submit a PR when your changes are **tested** and ready for review. +- Fill in the [PR template](/.github/pull_request_template.md). +- This repository is a mirror image of the upstream [NGINX Docker image](https://github.com/nginxinc/docker-nginx) with minor changes in order to support running NGINX in an unprivileged environment. As such only two types of PRs will be considered: -### Open a Pull Request + 1. PRs that incorporate changes made to the upstream image that have not yet been ported to this image (e.g. there's a new NGINX release). + 2. PRs that add a critical feature or a nice-to-have enhancement for running these images on an unprivileged environment (e.g. allowing users specify to the UID/GID of the image user). -* Fork the repo, create a branch, implement your changes, test that the corresponding Docker images can be built and run as intended, and submit a PR when your changes are **tested** and ready for review. -* Fill in [our pull request template](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/.github/pull_request_template.md). +**Note:** If you'd like to implement a new feature, please consider creating a [feature request issue](/.github/ISSUE_TEMPLATE/feature_request.yml) first to start a discussion about the feature. -Note: if you'd like to implement a new feature, please consider creating a feature request issue first to start a discussion about the feature. +#### F5 Contributor License Agreement (CLA) -## Code Guidelines +F5 requires all contributors to agree to the terms of the F5 CLA (available [here](https://github.com/f5/f5-cla/.github/blob/main/docs/f5_cla.md)) before any of their changes can be incorporated into an F5 Open Source repository (even contributions to the F5 CLA itself!). + +If you have not yet agreed to the F5 CLA terms and submit a PR to this repository, a bot will prompt you to view and agree to the F5 CLA. You will have to agree to the F5 CLA terms through a comment in the PR before any of your changes can be merged. Your agreement signature will be safely stored by F5 and no longer be required in future PRs. -### Docker NGINX Unprivileged Guidelines +## Code Guidelines -Given this repository is a mirror image of the upstream [Docker NGINX image](https://github.com/nginxinc/docker-nginx), only two types of PRs will be considered: +### Docker Guidelines -1. PRs that incorporate changes made to upstream images (e.g. there's a new NGINX release). -2. PRs that add a critical feature or a nice-to-have enhancement for running these images on an unprivileged environment (e.g. allowing users specify to the UID/GID of the image user). +- Update any entrypoint scripts via the the scripts contained in the [`/entrypoint`](/entrypoint) directory. +- Update any Dockerfiles via the Dockerfile templates in the root directory (e.g. [`Dockerfile-alpine.template`](/Dockerfile-alpine.template)). +- Run the [`./update.sh`](/update.sh) script to apply all entrypoint/Dockerfile template changes to the relevant image entrypoints & Dockerfiles. ### Git Guidelines -* Keep a clean, concise and meaningful git commit history on your branch (within reason), rebasing locally and squashing before submitting a PR. -* Follow the guidelines of writing a good commit message as described here <https://chris.beams.io/posts/git-commit/> and summarised in the next few points: - * In the subject line, use the present tense ("Add feature" not "Added feature"). - * In the subject line, use the imperative mood ("Move cursor to..." not "Moves cursor to..."). - * Limit the subject line to 72 characters or less. - * Reference issues and pull requests liberally after the subject line. - * Add more detailed description in the body of the git message (`git commit -a` to give you more space and time in your text editor to write a good message instead of `git commit -am`). +- Keep a clean, concise and meaningful git commit history on your branch (within reason), rebasing locally and squashing before submitting a PR. +- If possible and/or relevant, use the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0/) format when writing a commit message, so that changelogs can be automatically generated. +- Follow the guidelines of writing a good commit message as described here <https://chris.beams.io/posts/git-commit/> and summarized in the next few points: + - In the subject line, use the present tense ("Add feature" not "Added feature"). + - In the subject line, use the imperative mood ("Move cursor to..." not "Moves cursor to..."). + - Limit the subject line to 72 characters or less. + - Reference issues and pull requests liberally after the subject line. + - Add more detailed description in the body of the git message (`git commit -a` to give you more space and time in your text editor to write a good message instead of `git commit -am`). diff --git a/README.md b/README.md index 8beb898..8b98139 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,18 @@ +[](https://securityscorecards.dev/viewer/?uri=github.com/nginx/docker-nginx-unprivileged) [](https://www.repostatus.org/#active) -[](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/SUPPORT.md) -[](https://github.com/nginxinc/docker-nginx-unprivileged/main/CODE_OF_CONDUCT.md) +[](/SUPPORT.md) +[](https://community.nginx.org) +[](https://opensource.org/license/apache-2-0) +[](/CODE_OF_CONDUCT.md) # NGINX Unprivileged Docker Image This repo contains a series of Dockerfiles to create an NGINX Docker image that runs NGINX as a non root, unprivileged user. Notable differences with respect to the official [NGINX Docker](https://github.com/nginxinc/docker-nginx) image include: -* The default NGINX listen port is now `8080` instead of `80` (this is no longer necessary as of Docker `20.03` but it's still required in other container runtimes) -* The default NGINX user directive in `/etc/nginx/nginx.conf` has been removed -* The default NGINX PID has been moved from `/var/run/nginx.pid` to `/tmp/nginx.pid` -* Change `*_temp_path` variables to `/tmp/*` +- The default NGINX listen port is now `8080` instead of `80` (this is no longer necessary as of Docker `20.03` but it's still required in other container runtimes) +- The default NGINX user directive in `/etc/nginx/nginx.conf` has been removed +- The default NGINX PID has been moved from `/var/run/nginx.pid` to `/tmp/nginx.pid` +- Change `*_temp_path` variables to `/tmp/*` New images are built and pushed to on a weekly basis (every Monday night). @@ -21,10 +24,10 @@ Check out the [docs](https://hub.docker.com/_/nginx) for the upstream Docker NGI You can find pre-built images in each of the following registries: -* Amazon ECR - <https://gallery.ecr.aws/nginx/nginx-unprivileged> -* Docker Hub - <https://hub.docker.com/r/nginxinc/nginx-unprivileged> -* GitHub Container Registry - <https://github.com/nginxinc/docker-nginx-unprivileged/pkgs/container/nginx-unprivileged> -* Quay - <https://quay.io/repository/nginx/nginx-unprivileged> +- Amazon ECR - <https://gallery.ecr.aws/nginx/nginx-unprivileged> +- Docker Hub - <https://hub.docker.com/r/nginxinc/nginx-unprivileged> +- GitHub Container Registry - <https://github.com/nginxinc/docker-nginx-unprivileged/pkgs/container/nginx-unprivileged> +- Quay - <https://quay.io/repository/nginx/nginx-unprivileged> ### Architectures @@ -32,15 +35,15 @@ Most images are built for the `amd64`, `arm32v5` (for Debian), `arm32v6` (for Al ## Troubleshooting Tips -* If you wish to use a different user ID and/or group ID when running the Docker Unprivileged image, rebuild the image using the following Docker build arguments: +- If you wish to use a different user ID and/or group ID when running the Docker Unprivileged image, rebuild the image using the following Docker build arguments: ```bash docker build --build-arg UID=<UID> --build-arg GID=<GID> -t nginx-unprivileged . ``` -* If you override the default `nginx.conf` file you may encounter various types of error messages: - * To fix `nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)`, you have to specify a valid `pid` location by adding the line `pid /tmp/nginx.pid;` at the top level of your config. - * To fix `nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system)`, you have to specify a valid location for the various NGINX temporary paths by adding these lines within the `http` context: +- If you override the default `nginx.conf` file you may encounter various types of error messages: + - To fix `nginx: [emerg] open() "/var/run/nginx.pid" failed (13: Permission denied)`, you have to specify a valid `pid` location by adding the line `pid /tmp/nginx.pid;` at the top level of your config. + - To fix `nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (30: Read-only file system)`, you have to specify a valid location for the various NGINX temporary paths by adding these lines within the `http` context: ```nginx http { @@ -53,7 +56,7 @@ Most images are built for the `amd64`, `arm32v5` (for Debian), `arm32v6` (for Al } ``` -## On Reporting Issues +## On Reporting Issues and Opening PRs Whilst issues and PRs are welcome, please do note that: @@ -63,10 +66,10 @@ Whilst issues and PRs are welcome, please do note that: ## Contributing -Please see the [contributing guide](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/CONTRIBUTING.md) for guidelines on how to best contribute to this project. +Please see the [contributing guide](/CONTRIBUTING.md) for guidelines on how to best contribute to this project. ## License -[Apache License, Version 2.0](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/LICENSE) +[Apache License, Version 2.0](/LICENSE) -© [F5, Inc.](https://www.f5.com/) 2018 - 2024 +© [F5, Inc.](https://www.f5.com/) 2018 - 2025 diff --git a/SECURITY.md b/SECURITY.md index 75d58e3..3e3607a 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,13 +2,20 @@ ## Latest Versions -We advise users to run or update to the most recent release of the NGINX Docker Unprivileged image. Older versions of the NGINX Docker Unprivileged image may not have all enhancements and/or bug fixes applied to them. +We advise users to run or update to the most recent release of the NGINX Docker unprivileged image. Older versions of the NGINX Docker unprivileged image may not have all enhancements and/or bug fixes applied to them. ## Reporting a Vulnerability -### Docker NGINX Unprivileged Image +The F5 Security Incident Response Team (F5 SIRT) offers two methods to easily report potential security vulnerabilities: -If you find a security vulnerability that directly affects a direct NGINX library dependency we encourage you open an issue detailing the security vulnerability. +- If youโre an F5 customer with an active support contract, please contact [F5 Technical Support](https://www.f5.com/support). +- If you arenโt an F5 customer, please report any potential or current instances of security vulnerabilities in any F5 product to the F5 Security Incident Response Team at <f5sirt@f5.com>. + +For more information, please read the F5 SIRT vulnerability reporting guidelines available at [https://www.f5.com/support/report-a-vulnerability](https://www.f5.com/support/report-a-vulnerability). + +## CVEs to be considered + +If you find a security vulnerability that directly affects a direct NGINX library dependency we encourage you open an issue detailing the security vulnerability. ***Only vulnerabilities related to to direct NGINX library dependencies will be considered. Other security vulnerabilities will be addressed by the weekly Monday night build and as such will be ignored/promptly closed.*** For reference, the direct NGINX library dependencies are: @@ -25,14 +32,3 @@ For reference, the direct NGINX library dependencies are: - `libpcre2` - `libssl` - `libz` - -***Note: Only vulnerabilities related to direct NGINX library dependencies will be considered. Other security vulnerabilities should be addressed by the weekly Monday night build and as such will be promptly closed.*** - -### Codebase - -If you find a security vulnerability that affects the codebase, we encourage you to report it to the F5 Security Incident Response Team (F5 SIRT): - -- If youโre an F5 customer with an active support contract, please contact [F5 Technical Support](https://www.f5.com/services/support). -- If you arenโt an F5 customer, please report any potential or current instances of security vulnerabilities with any F5 product to the F5 Security Incident Response Team at <F5SIRT@f5.com>. - -For more information visit [https://www.f5.com/services/support/report-a-vulnerability](https://www.f5.com/services/support/report-a-vulnerability). diff --git a/SUPPORT.md b/SUPPORT.md index bbcd998..0d9c8b4 100644 --- a/SUPPORT.md +++ b/SUPPORT.md @@ -4,25 +4,21 @@ We use GitHub for tracking bugs and feature requests related to all the Docker NGINX images (including all variants and container registries). -Don't know how something in this project works? Curious if this project can achieve your desired functionality? Please open an issue on GitHub with the label `question`. +Don't know how something in this project works? Curious if this project can achieve your desired functionality? Please open an issue on GitHub with the label `question`. Alternatively, start a GitHub discussion! ## NGINX Specific Questions and/or Issues This isn't the right place to get support for NGINX specific questions, but the following resources are available below. Thanks for your understanding! -### Community Slack +### Community Forum -We have a community [Slack](https://nginxcommunity.slack.com/)! - -If you are not a member, click [here](https://community.nginx.org/joinslack) to sign up (and let us know if the link does not seem to be working!) - -Once you join, check out the `#beginner-questions` and `nginx-users` channels :) +We have a community [forum](https://community.nginx.org/)! If you have any questions and/or issues, try checking out the [`Troubleshooting`](https://community.nginx.org/c/troubleshooting/8) and [`How do I...?`](https://community.nginx.org/c/how-do-i/9) categories. Both fellow community members and NGINXers might be able to help you! :) ### Documentation For a comprehensive list of all NGINX directives, check out <https://nginx.org>. -For a comprehensive list of admin and deployment guides for all NGINX products, check out <https://docs.nginx.com>. +For a comprehensive list of administration and deployment guides for all NGINX products, check out <https://docs.nginx.com>. ### Mailing List @@ -30,8 +26,12 @@ Want to get in touch with the NGINX development team directly? Try using the rel ## Contributing -Please see the [contributing guide](https://github.com/nginxinc/docker-nginx-unprivileged/blob/main/CONTRIBUTING.md) for guidelines on how to best contribute to this project. +Please see the [contributing guide](/CONTRIBUTING.md) for guidelines on how to best contribute to this project. ## Commercial Support -Commercial support for this project may be available. Please get in touch with [NGINX sales](https://www.nginx.com/contact-sales/) or check your contract details for more info! +Commercial support for this project may be available. Please get in touch with [NGINX sales](https://www.f5.com/products/get-f5/) or check your contract details for more info! + +## Community Support + +Community support is offered on a best effort basis through either GitHub issues/PRs/discussions or through any of our active communities.