From 8d7f242b56a1563efa4a8ac59df579c8481da5f8 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Tue, 16 Jan 2024 20:05:22 -0800 Subject: [PATCH 1/4] Build NGINX Plus images Problem: Building the NGINX Plus image is a manual step Solution: Add automated build in the pipeline --- .github/workflows/build.yml | 155 ++++++++++++++++++ .github/workflows/ci.yml | 94 +---------- .github/workflows/update-docker-images.yml | 81 +-------- Makefile | 2 +- build/Dockerfile | 2 +- build/Dockerfile.nginx | 2 +- build/Dockerfile.nginxplus | 21 ++- conformance/tests/Dockerfile | 2 +- debug/Dockerfile | 2 +- docs/developer/quickstart.md | 8 +- docs/developer/release-process.md | 2 +- .../installation/building-the-images.md | 4 +- 12 files changed, 195 insertions(+), 180 deletions(-) create mode 100644 .github/workflows/build.yml diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000000..6de38021af --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,155 @@ +name: Build + +on: + workflow_call: + inputs: + platforms: + required: true + type: string + image: + required: true + type: string + tag: + required: false + type: string + +defaults: + run: + shell: bash + +permissions: + contents: read + +jobs: + build: + permissions: + contents: read # for docker/build-push-action to read repo content + security-events: write # for github/codeql-action/upload-sarif to upload SARIF results + packages: write # for docker/build-push-action to push to GHCR + id-token: write # for docker/login to login to NGINX registry + runs-on: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus') && 'kic-plus' || 'ubuntu-22.04' }} + services: + registry: + image: registry:2 + ports: + - 5000:5000 + steps: + - name: Checkout Repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ inputs.tag != '' && format('refs/tags/v{0}', inputs.tag) || github.ref }} + + - name: Fetch Cached Artifacts + uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 + with: + path: ${{ github.workspace }}/dist + key: nginx-gateway-fabric-${{ github.run_id }}-${{ github.run_number }} + + - name: Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + with: + driver-opts: network=host + + - name: Setup QEMU + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + with: + platforms: arm64 + + - name: Login to GitHub Container Registry + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + if: ${{ github.event_name != 'pull_request' && ! contains(inputs.image, 'plus') }} + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get Id Token + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + id: idtoken + with: + script: | + let id_token = await core.getIDToken() + core.setOutput('id_token', id_token) + if: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus')}} + + - name: Login to NGINX Registry + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: docker-mgmt.nginx.com + username: ${{ steps.idtoken.outputs.id_token }} + password: ${{ github.actor }} + if: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus') }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 + with: + images: | + name=ghcr.io/nginxinc/nginx-gateway-fabric,enable=${{ inputs.image == 'ngf' && github.event_name != 'pull_request' }} + name=ghcr.io/nginxinc/nginx-gateway-fabric/nginx,enable=${{ inputs.image == 'nginx' && github.event_name != 'pull_request' }} + name=docker-mgmt.nginx.com/nginx-gateway-fabric/nginx-plus,enable=${{ inputs.image == 'nginx-plus' && github.event_name != 'pull_request' }} + name=localhost:5000/nginx-gateway-fabric/${{ inputs.image }} + flavor: | + latest=${{ (inputs.tag != '' && 'true') || 'auto' }} + tags: | + type=semver,pattern={{version}} + type=edge + type=ref,event=pr + type=ref,event=branch,suffix=-rc,enable=${{ startsWith(github.ref, 'refs/heads/release') }} + type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }} + labels: | + org.opencontainers.image.documentation=https://docs.nginx.com/nginx-gateway-fabric + org.opencontainers.image.vendor=NGINX Inc + env: + DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + + - name: Build Docker Image + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 + with: + file: build/Dockerfile${{ inputs.image == 'nginx' && '.nginx' || '' }}${{ inputs.image == 'nginx-plus' && '.nginxplus' || '' }} + context: "." + target: ${{ inputs.image == 'ngf' && 'goreleaser' || '' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} + push: true + platforms: ${{ inputs.platforms }} + cache-from: type=gha,scope=${{ inputs.image }} + cache-to: type=gha,scope=${{ inputs.image }},mode=max + pull: true + no-cache: ${{ github.event_name != 'pull_request' }} + sbom: true + provenance: true + build-args: | + NJS_DIR=internal/mode/static/nginx/modules/src + NGINX_CONF_DIR=internal/mode/static/nginx/conf + BUILD_AGENT=gha + secrets: | + ${{ contains(inputs.image, 'plus') && format('"nginx-repo.crt={0}"', secrets.NGINX_CRT) || '' }} + ${{ contains(inputs.image, 'plus') && format('"nginx-repo.key={0}"', secrets.NGINX_KEY) || '' }} + + - name: Inspect SBOM + run: | + docker buildx imagetools inspect localhost:5000/nginx-gateway-fabric/${{ inputs.image }}:${{ steps.meta.outputs.version }} --format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sbom-${{ inputs.image }}.json + + - name: Scan SBOM + id: scan + uses: anchore/scan-action@1d59d90b47fc11ff8f97822da6c25eec888f81cf # v3.5.0 + with: + sbom: "sbom-${{ inputs.image }}.json" + only-fixed: true + add-cpes-if-none: true + + - name: Upload scan result to GitHub Security tab + uses: github/codeql-action/upload-sarif@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0 + continue-on-error: true + with: + sarif_file: ${{ steps.scan.outputs.sarif }} + + - name: Upload Scan Results + uses: actions/upload-artifact@1eb3cb2b3e0f29609092a73eb033bb759a334595 # v4.1.0 + continue-on-error: true + with: + name: scan-results-${{ inputs.image }}.sarif + path: ${{ steps.scan.outputs.sarif }} + if: always() diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b53d782b2f..c047af6140 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,9 +17,6 @@ concurrency: group: ${{ github.ref_name }}-ci cancel-in-progress: true -env: - platforms: "linux/arm64, linux/amd64" - permissions: contents: read @@ -245,97 +242,22 @@ jobs: build: name: Build Image - runs-on: ubuntu-22.04 needs: [vars, binary] strategy: fail-fast: false matrix: - container: [ngf, nginx] + image: [ngf, nginx, nginx-plus] + platforms: ["linux/arm64, linux/amd64"] + uses: ./.github/workflows/build.yml + with: + image: ${{ matrix.image }} + platforms: ${{ matrix.platforms }} permissions: contents: read # for docker/build-push-action to read repo content security-events: write # for github/codeql-action/upload-sarif to upload SARIF results packages: write # for docker/build-push-action to push to GHCR - steps: - - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Fetch Cached Artifacts - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - with: - path: ${{ github.workspace }}/dist - key: nginx-gateway-fabric-${{ github.run_id }}-${{ github.run_number }} - - - name: Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - - - name: Setup QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - with: - platforms: arm64 - - - name: Login to GitHub Container Registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - if: ${{ github.event_name != 'pull_request' }} - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 - with: - images: | - name=ghcr.io/nginxinc/nginx-gateway-fabric${{ matrix.container == 'nginx' && '/nginx' || '' }} - tags: | - type=semver,pattern={{version}} - type=edge - type=ref,event=pr - type=ref,event=branch,suffix=-rc,enable=${{ startsWith(github.ref, 'refs/heads/release') }} - - - name: Build Docker Image - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 - with: - file: ${{ matrix.container == 'nginx' && 'build/Dockerfile.nginx' || 'build/Dockerfile' }} - context: "." - target: ${{ matrix.container == 'ngf' && 'goreleaser' || '' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - load: ${{ github.event_name == 'pull_request' }} - push: ${{ github.event_name != 'pull_request' }} - platforms: ${{ github.event_name != 'pull_request' && env.platforms || '' }} - cache-from: type=gha,scope=${{ matrix.container }} - cache-to: type=gha,scope=${{ matrix.container }},mode=max - pull: true - no-cache: ${{ github.event_name != 'pull_request' }} - sbom: ${{ github.event_name != 'pull_request' }} - provenance: false - build-args: | - NJS_DIR=internal/mode/static/nginx/modules/src - NGINX_CONF_DIR=internal/mode/static/nginx/conf - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca # 0.16.1 - continue-on-error: true - with: - image-ref: ghcr.io/nginxinc/nginx-gateway-fabric${{ matrix.container == 'nginx' && '/nginx' || '' }}:${{ steps.meta.outputs.version }} - format: "sarif" - output: trivy-results-nginx-gateway-fabric${{ matrix.container == 'nginx' && '-nginx' || '' }}.sarif - ignore-unfixed: "true" - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2 - continue-on-error: true - with: - sarif_file: trivy-results-nginx-gateway-fabric${{ matrix.container == 'nginx' && '-nginx' || '' }}.sarif - - - name: Upload Scan Results - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 - continue-on-error: true - with: - name: trivy-results-nginx-gateway-fabric${{ matrix.container == 'nginx' && '-nginx' || '' }}.sarif - path: trivy-results-nginx-gateway-fabric${{ matrix.container == 'nginx' && '-nginx' || '' }}.sarif - if: always() + id-token: write # for docker/login to login to NGINX registry + secrets: inherit publish-helm: name: Package and Publish Helm Chart diff --git a/.github/workflows/update-docker-images.yml b/.github/workflows/update-docker-images.yml index 386536d528..8e8f78b8c9 100644 --- a/.github/workflows/update-docker-images.yml +++ b/.github/workflows/update-docker-images.yml @@ -15,9 +15,6 @@ concurrency: permissions: contents: read -env: - platforms: "linux/arm64, linux/amd64" - jobs: variables: name: Get versions of base images @@ -61,86 +58,22 @@ jobs: with: base-image: ${{ needs.variables.outputs.nginx_version }} image: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:${{ needs.variables.outputs.ngf_tag }} - platforms: ${{ env.platforms }} + platforms: "linux/arm64, linux/amd64" - id: needs run: echo "needs-updating=${{ steps.update.outputs.needs-updating }}" >> $GITHUB_OUTPUT build: name: Build Image - runs-on: ubuntu-22.04 needs: [variables, check] if: ${{ needs.check.outputs.needs-updating }} - strategy: - fail-fast: false + uses: ./.github/workflows/build.yml + with: + image: nginx + platforms: "linux/arm64, linux/amd64" + tag: ${{ needs.variables.outputs.ngf_tag }} permissions: contents: read # for docker/build-push-action to read repo content security-events: write # for github/codeql-action/upload-sarif to upload SARIF results packages: write # for docker/build-push-action to push to GHCR - steps: - - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - - - name: Setup QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - with: - platforms: arm64 - - - name: Login to GitHub Container Registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 - with: - images: | - name=ghcr.io/nginxinc/nginx-gateway-fabric/nginx - tags: | - ${{ needs.variables.outputs.ngf_tag }} - - - name: Build Docker Image - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 - with: - file: 'build/Dockerfile.nginx' - context: "." - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - push: true - platforms: ${{ env.platforms }} - pull: true - no-cache: true - sbom: true - provenance: false - build-args: | - NJS_DIR=internal/mode/static/nginx/modules/src - NGINX_CONF_DIR=internal/mode/static/nginx/conf - - - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca # 0.16.1 - continue-on-error: true - with: - image-ref: ghcr.io/nginxinc/nginx-gateway-fabric/nginx:${{ needs.variables.outputs.ngf_tag }} - format: "sarif" - output: trivy-results-nginx-gateway-fabric-nginx - ignore-unfixed: "true" - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2 - continue-on-error: true - with: - sarif_file: trivy-results-nginx-gateway-fabric-nginx - - - name: Upload Scan Results - uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 - continue-on-error: true - with: - name: trivy-results-nginx-gateway-fabric-nginx - path: trivy-results-nginx-gateway-fabric-nginx - if: always() + id-token: write # for docker/login to login to NGINX registry diff --git a/Makefile b/Makefile index 9a045be7a3..872723c00c 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,7 @@ GO_LINKER_FLAGS = $(GO_LINKER_FLAGS_OPTIMIZATIONS) $(GO_LINKER_FlAGS_VARS) # variables that can be overridden by the user PREFIX ?= nginx-gateway-fabric## The name of the NGF image. For example, nginx-gateway-fabric NGINX_PREFIX ?= $(PREFIX)/nginx## The name of the nginx image. For example: nginx-gateway-fabric/nginx -NGINX_PLUS_PREFIX ?= $(PREFIX)/nginxplus## The name of the nginx plus image. For example: nginx-gateway-fabric/nginxplus +NGINX_PLUS_PREFIX ?= $(PREFIX)/nginx-plus## The name of the nginx plus image. For example: nginx-gateway-fabric/nginx-plus TAG ?= $(VERSION:v%=%)## The tag of the image. For example, 0.3.0 TARGET ?= local## The target of the build. Possible values: local and container KIND_KUBE_CONFIG=$${HOME}/.kube/kind/config## The location of the kind kubeconfig diff --git a/build/Dockerfile b/build/Dockerfile index ef6862b3a8..f2fc69b176 100644 --- a/build/Dockerfile +++ b/build/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.4 +# syntax=docker/dockerfile:1.6 FROM golang:1.21 as builder WORKDIR /go/src/github.com/nginxinc/nginx-gateway-fabric diff --git a/build/Dockerfile.nginx b/build/Dockerfile.nginx index ed453a0421..3c58c8659b 100644 --- a/build/Dockerfile.nginx +++ b/build/Dockerfile.nginx @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.4 +# syntax=docker/dockerfile:1.6 FROM nginx:1.25.3-alpine ARG NJS_DIR diff --git a/build/Dockerfile.nginxplus b/build/Dockerfile.nginxplus index b151d187f6..b27b7f70f1 100644 --- a/build/Dockerfile.nginxplus +++ b/build/Dockerfile.nginxplus @@ -1,4 +1,10 @@ -# syntax=docker/dockerfile:1.4 +# syntax=docker/dockerfile:1.6 +FROM scratch as nginx-files + +# the following links can be replaced with local files if needed, i.e. ADD --chown=101:1001 +ADD --link --chown=101:1001 https://cs.nginx.com/static/keys/nginx_signing.rsa.pub nginx_signing.rsa.pub + + FROM alpine:3.19 ARG NGINX_PLUS_VERSION=R31 @@ -7,18 +13,17 @@ ARG NGINX_CONF_DIR ARG BUILD_AGENT RUN --mount=type=secret,id=nginx-repo.crt,dst=/etc/apk/cert.pem,mode=0644 \ - --mount=type=secret,id=nginx-repo.key,dst=/etc/apk/cert.key,mode=0644 \ - addgroup -g 1001 -S nginx \ + --mount=type=secret,id=nginx-repo.key,dst=/etc/apk/cert.key,mode=0644 \ + --mount=type=bind,from=nginx-files,src=nginx_signing.rsa.pub,target=/etc/apk/keys/nginx_signing.rsa.pub \ + addgroup -g 1001 -S nginx \ && adduser -S -D -H -u 101 -h /var/cache/nginx -s /sbin/nologin -G nginx -g nginx nginx \ - && wget -nv -O /etc/apk/keys/nginx_signing.rsa.pub https://cs.nginx.com/static/keys/nginx_signing.rsa.pub \ - && printf "%s\n" "https://pkgs.nginx.com/plus/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ - && apk add --no-cache nginx-plus nginx-plus-module-njs libcap \ - && ldconfig /usr/local/lib/ \ + && printf "%s\n" "https://pkgs.nginx.com/plus/${NGINX_PLUS_VERSION}/alpine/v$(grep -E -o '^[0-9]+\.[0-9]+' /etc/alpine-release)/main" >> /etc/apk/repositories \ + && apk add --no-cache nginx-plus nginx-plus-module-njs libcap \ && mkdir -p /var/lib/nginx /usr/lib/nginx/modules \ && setcap 'cap_net_bind_service=+ep' /usr/sbin/nginx \ && setcap -v 'cap_net_bind_service=+ep' /usr/sbin/nginx \ && apk del libcap \ - # forward request and error logs to docker log collector + # forward request and error logs to docker log collector && ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log diff --git a/conformance/tests/Dockerfile b/conformance/tests/Dockerfile index 7a60c0cd93..42b43f63ed 100644 --- a/conformance/tests/Dockerfile +++ b/conformance/tests/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.5 +# syntax=docker/dockerfile:1.6 # this is here so we can grab the latest version of kind and have dependabot keep it up to date FROM kindest/node:v1.29.0 diff --git a/debug/Dockerfile b/debug/Dockerfile index b9d36763a6..2ce6eda2ed 100644 --- a/debug/Dockerfile +++ b/debug/Dockerfile @@ -1,4 +1,4 @@ -# syntax=docker/dockerfile:1.5 +# syntax=docker/dockerfile:1.6 # This Dockerfile builds an image with the dlv debugger. See the debugging guide in the developer docs for details # on how to use it. FROM golang:1.21-alpine AS builder diff --git a/docs/developer/quickstart.md b/docs/developer/quickstart.md index 53c0ef0f28..b339484ea8 100644 --- a/docs/developer/quickstart.md +++ b/docs/developer/quickstart.md @@ -100,7 +100,7 @@ To build the NGINX Gateway Fabric and NGINX Plus container images from source ru make TAG=$(whoami) build-images-with-plus ``` -This will build the docker images `nginx-gateway-fabric:` and `nginx-gateway-fabric/nginxplus:`. +This will build the docker images `nginx-gateway-fabric:` and `nginx-gateway-fabric/nginx-plus:`. ## Deploy on Kind @@ -119,7 +119,7 @@ This will build the docker images `nginx-gateway-fabric:` and `nginx- or ```shell - kind load docker-image nginx-gateway-fabric:$(whoami) nginx-gateway-fabric/nginxplus:$(whoami) + kind load docker-image nginx-gateway-fabric:$(whoami) nginx-gateway-fabric/nginx-plus:$(whoami) ``` 3. Install Gateway API CRDs: @@ -139,7 +139,7 @@ This will build the docker images `nginx-gateway-fabric:` and `nginx- - To install NGINX Plus with Helm (where your release name is `my-release`): ```shell - helm install my-release ./deploy/helm-chart --create-namespace --wait --set service.type=NodePort --set nginxGateway.image.repository=nginx-gateway-fabric --set nginxGateway.image.tag=$(whoami) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=nginx-gateway-fabric/nginxplus --set nginx.image.tag=$(whoami) --set nginx.image.pullPolicy=Never --set nginx.plus=true -n nginx-gateway + helm install my-release ./deploy/helm-chart --create-namespace --wait --set service.type=NodePort --set nginxGateway.image.repository=nginx-gateway-fabric --set nginxGateway.image.tag=$(whoami) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=nginx-gateway-fabric/nginx-plus --set nginx.image.tag=$(whoami) --set nginx.image.pullPolicy=Never --set nginx.plus=true -n nginx-gateway ``` > For more information on Helm configuration options see the Helm [README](../../deploy/helm-chart/README.md). @@ -156,7 +156,7 @@ This will build the docker images `nginx-gateway-fabric:` and `nginx- - To install NGINX Plus with manifests: ```shell - make generate-manifests HELM_TEMPLATE_COMMON_ARGS="--set nginxGateway.image.repository=nginx-gateway-fabric --set nginxGateway.image.tag=$(whoami) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=nginx-gateway-fabric/nginxplus --set nginx.image.tag=$(whoami) --set nginx.image.pullPolicy=Never --set nginx.plus=true" + make generate-manifests HELM_TEMPLATE_COMMON_ARGS="--set nginxGateway.image.repository=nginx-gateway-fabric --set nginxGateway.image.tag=$(whoami) --set nginxGateway.image.pullPolicy=Never --set nginx.image.repository=nginx-gateway-fabric/nginx-plus --set nginx.image.tag=$(whoami) --set nginx.image.pullPolicy=Never --set nginx.plus=true" kubectl apply -f deploy/manifests/crds kubectl apply -f deploy/manifests/nginx-gateway.yaml kubectl apply -f deploy/manifests/service/nodeport.yaml diff --git a/docs/developer/release-process.md b/docs/developer/release-process.md index 59f381f180..8b7c983772 100644 --- a/docs/developer/release-process.md +++ b/docs/developer/release-process.md @@ -55,7 +55,7 @@ To create a new release, follow these steps: the [GitHub releases](https://github.com/nginxinc/nginx-gateway-fabric/releases) after the release branch is created. Use the previous changelog entries for formatting and content guidance. 9. Create and push the release tag in the format `vX.Y.Z`. As a result, the CI/CD pipeline will: - - Build NGF container images with the release tag `X.Y.Z` and push it to the registry. + - Build NGF, NGINX and NGINX Plus container images with the release tag `X.Y.Z` and push them to the registries. - Package and publish the Helm chart to the registry. - Create a GitHub release with an autogenerated changelog and attached release artifacts. 10. Prepare and merge a PR into the main branch to update the [README](/README.md) to include the information about diff --git a/site/content/installation/building-the-images.md b/site/content/installation/building-the-images.md index 95b0b187e8..8b8b3eb985 100644 --- a/site/content/installation/building-the-images.md +++ b/site/content/installation/building-the-images.md @@ -64,7 +64,7 @@ If building the NGINX Plus image, you will also need a valid NGINX Plus license ``` Set the `PREFIX` variable to the name of the registry you'd like to push the image to. By default, the images will be - named `nginx-gateway-fabric:edge` and `nginx-gateway-fabric/nginx:edge` or `nginx-gateway-fabric/nginxplus:edge`. + named `nginx-gateway-fabric:edge` and `nginx-gateway-fabric/nginx:edge` or `nginx-gateway-fabric/nginx-plus:edge`. 1. Push the images to your container registry: @@ -77,7 +77,7 @@ If building the NGINX Plus image, you will also need a valid NGINX Plus license ```shell docker push myregistry.example.com/nginx-gateway-fabric:edge - docker push myregistry.example.com/nginx-gateway-fabric/nginxplus:edge + docker push myregistry.example.com/nginx-gateway-fabric/nginx-plus:edge ``` Make sure to substitute `myregistry.example.com/nginx-gateway-fabric` with your registry. From 08a0423b9c3814d4a535571dbdb46fc36b104bac Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Mon, 29 Jan 2024 21:08:49 -0800 Subject: [PATCH 2/4] update deps --- .github/workflows/build.yml | 260 ++++++++++++++++++------------------ 1 file changed, 130 insertions(+), 130 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6de38021af..b7710a5cf6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,17 +1,17 @@ name: Build on: - workflow_call: - inputs: - platforms: - required: true - type: string - image: - required: true - type: string - tag: - required: false - type: string + workflow_call: + inputs: + platforms: + required: true + type: string + image: + required: true + type: string + tag: + required: false + type: string defaults: run: @@ -34,122 +34,122 @@ jobs: ports: - 5000:5000 steps: - - name: Checkout Repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - with: - ref: ${{ inputs.tag != '' && format('refs/tags/v{0}', inputs.tag) || github.ref }} - - - name: Fetch Cached Artifacts - uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 - with: - path: ${{ github.workspace }}/dist - key: nginx-gateway-fabric-${{ github.run_id }}-${{ github.run_number }} - - - name: Docker Buildx - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 - with: - driver-opts: network=host - - - name: Setup QEMU - uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 - with: - platforms: arm64 - - - name: Login to GitHub Container Registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - if: ${{ github.event_name != 'pull_request' && ! contains(inputs.image, 'plus') }} - with: - registry: ghcr.io - username: ${{ github.repository_owner }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Get Id Token - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - id: idtoken - with: - script: | - let id_token = await core.getIDToken() - core.setOutput('id_token', id_token) - if: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus')}} - - - name: Login to NGINX Registry - uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 - with: - registry: docker-mgmt.nginx.com - username: ${{ steps.idtoken.outputs.id_token }} - password: ${{ github.actor }} - if: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus') }} - - - name: Docker meta - id: meta - uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 - with: - images: | - name=ghcr.io/nginxinc/nginx-gateway-fabric,enable=${{ inputs.image == 'ngf' && github.event_name != 'pull_request' }} - name=ghcr.io/nginxinc/nginx-gateway-fabric/nginx,enable=${{ inputs.image == 'nginx' && github.event_name != 'pull_request' }} - name=docker-mgmt.nginx.com/nginx-gateway-fabric/nginx-plus,enable=${{ inputs.image == 'nginx-plus' && github.event_name != 'pull_request' }} - name=localhost:5000/nginx-gateway-fabric/${{ inputs.image }} - flavor: | - latest=${{ (inputs.tag != '' && 'true') || 'auto' }} - tags: | - type=semver,pattern={{version}} - type=edge - type=ref,event=pr - type=ref,event=branch,suffix=-rc,enable=${{ startsWith(github.ref, 'refs/heads/release') }} - type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }} - labels: | - org.opencontainers.image.documentation=https://docs.nginx.com/nginx-gateway-fabric - org.opencontainers.image.vendor=NGINX Inc - env: - DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index - - - name: Build Docker Image - uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 - with: - file: build/Dockerfile${{ inputs.image == 'nginx' && '.nginx' || '' }}${{ inputs.image == 'nginx-plus' && '.nginxplus' || '' }} - context: "." - target: ${{ inputs.image == 'ngf' && 'goreleaser' || '' }} - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} - annotations: ${{ steps.meta.outputs.annotations }} - push: true - platforms: ${{ inputs.platforms }} - cache-from: type=gha,scope=${{ inputs.image }} - cache-to: type=gha,scope=${{ inputs.image }},mode=max - pull: true - no-cache: ${{ github.event_name != 'pull_request' }} - sbom: true - provenance: true - build-args: | - NJS_DIR=internal/mode/static/nginx/modules/src - NGINX_CONF_DIR=internal/mode/static/nginx/conf - BUILD_AGENT=gha - secrets: | - ${{ contains(inputs.image, 'plus') && format('"nginx-repo.crt={0}"', secrets.NGINX_CRT) || '' }} - ${{ contains(inputs.image, 'plus') && format('"nginx-repo.key={0}"', secrets.NGINX_KEY) || '' }} - - - name: Inspect SBOM - run: | - docker buildx imagetools inspect localhost:5000/nginx-gateway-fabric/${{ inputs.image }}:${{ steps.meta.outputs.version }} --format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sbom-${{ inputs.image }}.json - - - name: Scan SBOM - id: scan - uses: anchore/scan-action@1d59d90b47fc11ff8f97822da6c25eec888f81cf # v3.5.0 - with: - sbom: "sbom-${{ inputs.image }}.json" - only-fixed: true - add-cpes-if-none: true - - - name: Upload scan result to GitHub Security tab - uses: github/codeql-action/upload-sarif@e5f05b81d5b6ff8cfa111c80c22c5fd02a384118 # v3.23.0 - continue-on-error: true - with: - sarif_file: ${{ steps.scan.outputs.sarif }} - - - name: Upload Scan Results - uses: actions/upload-artifact@1eb3cb2b3e0f29609092a73eb033bb759a334595 # v4.1.0 - continue-on-error: true - with: - name: scan-results-${{ inputs.image }}.sarif - path: ${{ steps.scan.outputs.sarif }} - if: always() + - name: Checkout Repository + uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 + with: + ref: ${{ inputs.tag != '' && format('refs/tags/v{0}', inputs.tag) || github.ref }} + + - name: Fetch Cached Artifacts + uses: actions/cache@13aacd865c20de90d75de3b17ebe84f7a17d57d2 # v4.0.0 + with: + path: ${{ github.workspace }}/dist + key: nginx-gateway-fabric-${{ github.run_id }}-${{ github.run_number }} + + - name: Docker Buildx + uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + with: + driver-opts: network=host + + - name: Setup QEMU + uses: docker/setup-qemu-action@68827325e0b33c7199eb31dd4e31fbe9023e06e3 # v3.0.0 + with: + platforms: arm64 + + - name: Login to GitHub Container Registry + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + if: ${{ github.event_name != 'pull_request' && ! contains(inputs.image, 'plus') }} + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Get Id Token + uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 + id: idtoken + with: + script: | + let id_token = await core.getIDToken() + core.setOutput('id_token', id_token) + if: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus')}} + + - name: Login to NGINX Registry + uses: docker/login-action@343f7c4344506bcbf9b4de18042ae17996df046d # v3.0.0 + with: + registry: docker-mgmt.nginx.com + username: ${{ steps.idtoken.outputs.id_token }} + password: ${{ github.actor }} + if: ${{ github.event_name != 'pull_request' && contains(inputs.image, 'plus') }} + + - name: Docker meta + id: meta + uses: docker/metadata-action@dbef88086f6cef02e264edb7dbf63250c17cef6c # v5.5.0 + with: + images: | + name=ghcr.io/nginxinc/nginx-gateway-fabric,enable=${{ inputs.image == 'ngf' && github.event_name != 'pull_request' }} + name=ghcr.io/nginxinc/nginx-gateway-fabric/nginx,enable=${{ inputs.image == 'nginx' && github.event_name != 'pull_request' }} + name=docker-mgmt.nginx.com/nginx-gateway-fabric/nginx-plus,enable=${{ inputs.image == 'nginx-plus' && github.event_name != 'pull_request' }} + name=localhost:5000/nginx-gateway-fabric/${{ inputs.image }} + flavor: | + latest=${{ (inputs.tag != '' && 'true') || 'auto' }} + tags: | + type=semver,pattern={{version}} + type=edge + type=ref,event=pr + type=ref,event=branch,suffix=-rc,enable=${{ startsWith(github.ref, 'refs/heads/release') }} + type=raw,value=${{ inputs.tag }},enable=${{ inputs.tag != '' }} + labels: | + org.opencontainers.image.documentation=https://docs.nginx.com/nginx-gateway-fabric + org.opencontainers.image.vendor=NGINX Inc + env: + DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index + + - name: Build Docker Image + uses: docker/build-push-action@4a13e500e55cf31b7a5d59a38ab2040ab0f42f56 # v5.1.0 + with: + file: build/Dockerfile${{ inputs.image == 'nginx' && '.nginx' || '' }}${{ inputs.image == 'nginx-plus' && '.nginxplus' || '' }} + context: "." + target: ${{ inputs.image == 'ngf' && 'goreleaser' || '' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + annotations: ${{ steps.meta.outputs.annotations }} + push: true + platforms: ${{ inputs.platforms }} + cache-from: type=gha,scope=${{ inputs.image }} + cache-to: type=gha,scope=${{ inputs.image }},mode=max + pull: true + no-cache: ${{ github.event_name != 'pull_request' }} + sbom: true + provenance: true + build-args: | + NJS_DIR=internal/mode/static/nginx/modules/src + NGINX_CONF_DIR=internal/mode/static/nginx/conf + BUILD_AGENT=gha + secrets: | + ${{ contains(inputs.image, 'plus') && format('"nginx-repo.crt={0}"', secrets.NGINX_CRT) || '' }} + ${{ contains(inputs.image, 'plus') && format('"nginx-repo.key={0}"', secrets.NGINX_KEY) || '' }} + + - name: Inspect SBOM + run: | + docker buildx imagetools inspect localhost:5000/nginx-gateway-fabric/${{ inputs.image }}:${{ steps.meta.outputs.version }} --format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sbom-${{ inputs.image }}.json + + - name: Scan SBOM + id: scan + uses: anchore/scan-action@1d59d90b47fc11ff8f97822da6c25eec888f81cf # v3.5.0 + with: + sbom: "sbom-${{ inputs.image }}.json" + only-fixed: true + add-cpes-if-none: true + + - name: Upload scan result to GitHub Security tab + uses: github/codeql-action/upload-sarif@b7bf0a3ed3ecfa44160715d7c442788f65f0f923 # v3.23.2 + continue-on-error: true + with: + sarif_file: ${{ steps.scan.outputs.sarif }} + + - name: Upload Scan Results + uses: actions/upload-artifact@26f96dfa697d77e81fd5907df203aa23a56210a8 # v4.3.0 + continue-on-error: true + with: + name: scan-results-${{ inputs.image }}.sarif + path: ${{ steps.scan.outputs.sarif }} + if: always() From a543b7dbee02c20917e6ddf83ebb48a568779d45 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Wed, 31 Jan 2024 12:41:10 -0800 Subject: [PATCH 3/4] Add Plus docs --- docs/developer/branching-and-workflow.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/developer/branching-and-workflow.md b/docs/developer/branching-and-workflow.md index 50c1f82695..f427dee643 100644 --- a/docs/developer/branching-and-workflow.md +++ b/docs/developer/branching-and-workflow.md @@ -56,3 +56,10 @@ branches. This practice helps maintain consistent labeling and allows for the au notes. For a comprehensive list of labels and prefixes, please refer to the [labeler](/.github/labeler.yml) file. + +## NGINX Plus Builds + +The CI/CD pipeline builds a Docker image for NGINX Plus from the NGINX Plus [Dockerfile](build/Dockerfile.nginxplus) for every commit to the `main` branch, the release branches and for every PR. +When a PR is opened, the CI/CD will use the cached image from the last build if the aren't any changes to the Dockerfile. If you're planning to make changes to the Dockerfile, +you would need to create a branch in the upstream repository. If you don't have write access to the upstream repository, you would need to contact the maintainers +and ask them to create a branch for you so that the changes to the Dockerfile can be cached. After that your PR from a forked repository will be able to use the cached image. From 3b87981ba49a78a72f0dd3fab71b8eea1b73c7d5 Mon Sep 17 00:00:00 2001 From: Luca Comellini Date: Wed, 31 Jan 2024 13:51:24 -0800 Subject: [PATCH 4/4] Update docs/developer/branching-and-workflow.md Co-authored-by: Kate Osborn <50597707+kate-osborn@users.noreply.github.com> --- docs/developer/branching-and-workflow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/developer/branching-and-workflow.md b/docs/developer/branching-and-workflow.md index f427dee643..ce0c0cc494 100644 --- a/docs/developer/branching-and-workflow.md +++ b/docs/developer/branching-and-workflow.md @@ -60,6 +60,6 @@ For a comprehensive list of labels and prefixes, please refer to the [labeler](/ ## NGINX Plus Builds The CI/CD pipeline builds a Docker image for NGINX Plus from the NGINX Plus [Dockerfile](build/Dockerfile.nginxplus) for every commit to the `main` branch, the release branches and for every PR. -When a PR is opened, the CI/CD will use the cached image from the last build if the aren't any changes to the Dockerfile. If you're planning to make changes to the Dockerfile, +When a PR is opened, the CI/CD will use the cached image from the last build if there aren't any changes to the Dockerfile. If you're planning to make changes to the Dockerfile, you would need to create a branch in the upstream repository. If you don't have write access to the upstream repository, you would need to contact the maintainers and ask them to create a branch for you so that the changes to the Dockerfile can be cached. After that your PR from a forked repository will be able to use the cached image.