From ae871d8ea30fbb3fa78579f3e31ca09ecd410065 Mon Sep 17 00:00:00 2001 From: Cees-Jan Kiewiet Date: Wed, 3 Sep 2025 16:04:45 +0200 Subject: [PATCH] Build (optional) multi arch support into our build toolkit --- .github/workflows/ci.yml | 661 +++++++++++---------------- Dockerfile-cli | 6 +- Dockerfile-fpm | 6 +- Dockerfile-http | 8 +- Makefile | 8 +- build-http.sh | 28 +- build-php.sh | 25 +- build-prometheus-exporter-file.sh | 23 +- src/php/utils/install-dumb-init | 2 +- src/php/utils/install-shush | 4 +- test-cli.sh | 4 +- test-fpm.sh | 4 +- test-http-e2e.sh | 2 +- test-http.sh | 2 +- test-prometheus-exporter-file-e2e.sh | 2 +- test/e2e/test_nginx_entrypoint.py | 5 + test/e2e/test_nginx_logs.py | 7 + test/security/docker-compose.yml | 21 - 18 files changed, 349 insertions(+), 469 deletions(-) delete mode 100644 test/security/docker-compose.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 273b6100..7df1883b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,16 @@ on: schedule: - cron: '3 3 * * 1' jobs: + supported-platforms: + name: Supported platforms + runs-on: ubuntu-latest + outputs: + platform: ${{ steps.supported-platform-matrix.outputs.platform }} + steps: + - id: supported-platform-matrix + name: Generate Platform list + run: | + echo "platform=[\"linux/amd64\",\"linux/arm64\"]" >> $GITHUB_OUTPUT supported-alpine-versions: name: Supported Alpine versions runs-on: ubuntu-latest @@ -21,7 +31,8 @@ jobs: name: Generate Alpine shell: bash run: | - echo "::set-output name=versions::[\"3.14\", \"3.13\", \"3.12\", \"3.11\"]" + echo "versions=[\"3.21\"]" >> $GITHUB_OUTPUT +# echo "versions=[\"3.22\",\"3.21\",\"3.19\"]" >> $GITHUB_OUTPUT supported-nginx-versions: name: Supported nginx versions runs-on: ubuntu-latest @@ -31,8 +42,8 @@ jobs: - id: supported-nginx-versions name: Generate nginx shell: bash - run: | # The "1.19-nginx1-nginx" in here will be changed to "1.19 nginx1 nginx" when calling ./build-http.sh - echo "::set-output name=versions::[\"1.19-nginx1-nginx\", \"1.18\"]" + run: | # The "1.29-nginx1-nginx" in here will be changed to "1.29 nginx1 nginx" when calling ./build-http.sh + echo "versions=[\"1.29-nginx1-nginx\", \"1.28\"]" >> $GITHUB_OUTPUT supported-php-versions: name: Supported PHP versions runs-on: ubuntu-latest @@ -43,7 +54,8 @@ jobs: name: Generate PHP shell: bash run: | - echo "::set-output name=versions::[\"7.4\", \"7.3\"]" + echo "versions=[\"8.3\"]" >> $GITHUB_OUTPUT +# echo "versions=[\"8.4\",\"8.3\",\"8.2\"]" >> $GITHUB_OUTPUT php-type-matrix: name: PHP Type Matrix runs-on: ubuntu-latest @@ -54,7 +66,7 @@ jobs: name: Generate Type shell: bash run: | - echo "::set-output name=type::[\"cli\", \"fpm\"]" + echo "type=[\"cli\", \"fpm\"]" >> $GITHUB_OUTPUT type-matrix: name: Type Matrix runs-on: ubuntu-latest @@ -67,7 +79,7 @@ jobs: name: Generate Type shell: bash run: | - echo "::set-output name=type::[\"cli\", \"fpm\", \"http\"]" + echo "type=[\"cli\", \"fpm\", \"http\"]" >> $GITHUB_OUTPUT lint-docker: name: Lint Dockerfile-${{ matrix.type }} runs-on: ubuntu-latest @@ -78,7 +90,7 @@ jobs: matrix: type: ${{ fromJson(needs.type-matrix.outputs.type) }} steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - name: Lint Dockerfile-${{ matrix.type }} uses: docker://hadolint/hadolint:latest-debian with: @@ -90,439 +102,241 @@ jobs: strategy: fail-fast: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v5 - id: files name: Generate shell script file list shell: bash run: | list=$(ls src/http/nginx/docker* src/php/utils/install-* src/php/utils/docker/* build* test-* | tr "\n" " " | sed -z '$ s/\n$//') - echo -e "::set-output name=list::/github/workspace/${list// / /github/workspace/}build-http.sh" + echo -e "list=/github/workspace/${list// / /github/workspace/}build-http.sh" >> $GITHUB_OUTPUT - name: Lint shell scripts uses: docker://koalaman/shellcheck:latest with: args: ${{ steps.files.outputs.list }} build-http: - name: Build nginx ${{ matrix.nginx }} + name: Build nginx ${{ matrix.nginx }} (${{ matrix.platform }}) needs: - lint-docker - lint-shell - supported-nginx-versions - runs-on: ubuntu-latest + - supported-platforms + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: nginx: ${{ fromJson(needs.supported-nginx-versions.outputs.nginx) }} + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - run: ./build-http.sh $(echo "${{ matrix.nginx }}" | tr '-' ' ') shell: bash - - run: cat ./tmp/build-http.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' % + env: + DOCKER_BUILD_PLATFORM: ${{ matrix.platform }} + - run: cat ./tmp/build-http-${{ env.PLATFORM_PAIR }}.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' % shell: bash - - run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./tmp/image-http-${{ matrix.nginx }}.tar + - run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./tmp/image-http-${{ matrix.nginx }}-${{ env.PLATFORM_PAIR }}.tar shell: bash - name: Upload Images uses: actions/upload-artifact@v4 with: - name: docker-image-http-${{ matrix.nginx }} + name: docker-image-http-${{ matrix.nginx }}-${{ env.PLATFORM_PAIR }} path: ./tmp build-prometheus-exporter-file: - name: Build prometheus-exporter-file + name: Build prometheus-exporter-file (${{ matrix.platform }}) needs: - lint-docker - lint-shell - runs-on: ubuntu-latest + - supported-platforms + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false + matrix: + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - run: make build-prometheus-exporter-file shell: bash - - run: cat ./tmp/build-prometheus-exporter-file.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' % + env: + DOCKER_BUILD_PLATFORM: ${{ matrix.platform }} + - run: cat ./tmp/build-prometheus-exporter-file-${{ env.PLATFORM_PAIR }}.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' % shell: bash - - run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./tmp/image-prometheus-exporter-file.tar + - run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./tmp/image-prometheus-exporter-file-${{ env.PLATFORM_PAIR }}.tar shell: bash - name: Upload Images uses: actions/upload-artifact@v4 with: - name: docker-image-prometheus-exporter-file + name: docker-image-prometheus-exporter-file-${{ env.PLATFORM_PAIR }} path: ./tmp build-php: - name: Build PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} + name: Build PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} (${{ matrix.platform }}) needs: - lint-docker - lint-shell - supported-alpine-versions - supported-php-versions + - supported-platforms - php-type-matrix - runs-on: ubuntu-latest + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: alpine: ${{ fromJson(needs.supported-alpine-versions.outputs.alpine) }} php: ${{ fromJson(needs.supported-php-versions.outputs.php) }} type: ${{ fromJson(needs.php-type-matrix.outputs.type) }} - include: - - php: "7.1" - alpine: "3.10" - type: cli - - php: "7.1" - alpine: "3.10" - type: fpm - - php: "8.0" - alpine: "3.14" - type: cli - - php: "8.0" - alpine: "3.14" - type: fpm - - php: "8.0" - alpine: "3.15" - type: cli - - php: "8.0" - alpine: "3.15" - type: fpm - - php: "8.0" - alpine: "3.16" - type: cli - - php: "8.0" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.15" - type: cli - - php: "8.1" - alpine: "3.15" - type: fpm - - php: "8.1" - alpine: "3.16" - type: cli - - php: "8.1" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.17" - type: cli - - php: "8.1" - alpine: "3.17" - type: fpm - - php: "8.2" - alpine: "3.17" - type: "cli" - - php: "8.2" - alpine: "3.17" - type: "fpm" - - php: "8.2" - alpine: "3.19" - type: "cli" - - php: "8.2" - alpine: "3.19" - type: "fpm" - - php: "8.2" - alpine: "3.22" - type: "cli" - - php: "8.2" - alpine: "3.22" - type: "fpm" - - php: "8.3" - alpine: "3.19" - type: "cli" - - php: "8.3" - alpine: "3.19" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "fpm" + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - run: ./build-php.sh ${{ matrix.type }} ${{ matrix.php }} ${{ matrix.alpine }} shell: bash - - run: cat ./tmp/build-${{ matrix.type }}.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' % + env: + DOCKER_BUILD_PLATFORM: ${{ matrix.platform }} + - run: cat ./tmp/build-${{ matrix.type }}-${{ env.PLATFORM_PAIR }}.tags | xargs -I % docker inspect --format='%={{.Id}}:{{index .Config.Env 7}}' % shell: bash - - run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./tmp/image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }}.tar + - run: docker save "${DOCKER_IMAGE}" | gzip -9 > ./tmp/image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }}-${{ env.PLATFORM_PAIR }}.tar shell: bash - name: Upload Images uses: actions/upload-artifact@v4 with: - name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }} + name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }}-${{ env.PLATFORM_PAIR }} path: ./tmp scan-vulnerability-php: - name: Scan PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} for vulnerabilities + name: Scan PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} for vulnerabilities (${{ matrix.platform }}) needs: - build-php - build-http - build-prometheus-exporter-file - supported-alpine-versions - supported-php-versions + - supported-platforms - php-type-matrix - runs-on: ubuntu-latest + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: alpine: ${{ fromJson(needs.supported-alpine-versions.outputs.alpine) }} php: ${{ fromJson(needs.supported-php-versions.outputs.php) }} type: ${{ fromJson(needs.php-type-matrix.outputs.type) }} - include: - - php: "7.1" - alpine: "3.10" - type: cli - - php: "7.1" - alpine: "3.10" - type: fpm - - php: "8.0" - alpine: "3.14" - type: cli - - php: "8.0" - alpine: "3.14" - type: fpm - - php: "8.0" - alpine: "3.15" - type: cli - - php: "8.0" - alpine: "3.15" - type: fpm - - php: "8.0" - alpine: "3.16" - type: cli - - php: "8.0" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.15" - type: cli - - php: "8.1" - alpine: "3.15" - type: fpm - - php: "8.1" - alpine: "3.16" - type: cli - - php: "8.1" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.17" - type: cli - - php: "8.1" - alpine: "3.17" - type: fpm - - php: "8.2" - alpine: "3.17" - type: "cli" - - php: "8.2" - alpine: "3.17" - type: "fpm" - - php: "8.2" - alpine: "3.19" - type: "cli" - - php: "8.2" - alpine: "3.19" - type: "fpm" - - php: "8.2" - alpine: "3.22" - type: "cli" - - php: "8.2" - alpine: "3.22" - type: "fpm" - - php: "8.3" - alpine: "3.19" - type: "cli" - - php: "8.3" - alpine: "3.19" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "fpm" + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 - - name: Install clair-scanner - shell: bash + - name: Prepare run: | - sudo curl -L https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 -o /usr/local/bin/clair-scanner - sudo chmod +x /usr/local/bin/clair-scanner + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - name: Download Docker image to scan uses: actions/download-artifact@v4.1.7 with: - name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }} + name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }}-${{ env.PLATFORM_PAIR }} path: ./tmp - run: docker load --input ./tmp/image*.tar - - run: mkdir -p "./clair/${DOCKER_IMAGE}" - run: make scan-vulnerability scan-vulnerability-http: - name: Scan nginx ${{ matrix.nginx }} for vulnerabilities + name: Scan nginx ${{ matrix.nginx }} for vulnerabilities (${{ matrix.platform }}) needs: - build-php - build-http - build-prometheus-exporter-file - supported-nginx-versions - runs-on: ubuntu-latest + - supported-platforms + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: nginx: ${{ fromJson(needs.supported-nginx-versions.outputs.nginx) }} + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 - - name: Install clair-scanner - shell: bash + - name: Prepare run: | - sudo curl -L https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 -o /usr/local/bin/clair-scanner - sudo chmod +x /usr/local/bin/clair-scanner + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - name: Download Docker image to scan uses: actions/download-artifact@v4.1.7 with: - name: docker-image-http-${{ matrix.nginx }} + name: docker-image-http-${{ matrix.nginx }}-${{ env.PLATFORM_PAIR }} path: ./tmp - run: docker load --input ./tmp/image*.tar shell: bash - - run: mkdir -p "./clair/${DOCKER_IMAGE}" - shell: bash - run: make scan-vulnerability shell: bash scan-vulnerability-prometheus-exporter-file: - name: Scan HTTP prometheus-exporter-file for vulnerabilities + name: Scan HTTP prometheus-exporter-file for vulnerabilities (${{ matrix.platform }}) needs: - build-php - build-http - build-prometheus-exporter-file - runs-on: ubuntu-latest + - supported-platforms + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false + matrix: + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 - - name: Install clair-scanner - shell: bash + - name: Prepare run: | - sudo curl -L https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 -o /usr/local/bin/clair-scanner - sudo chmod +x /usr/local/bin/clair-scanner + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - name: Download Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-prometheus-exporter-file + name: docker-image-prometheus-exporter-file-${{ env.PLATFORM_PAIR }} path: ./tmp - run: docker load --input ./tmp/image*.tar - - run: mkdir -p "./clair/${DOCKER_IMAGE}" - run: make scan-vulnerability test-php: - name: Functionaly test PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} + name: Functionaly test PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} (${{ matrix.platform }}) needs: - build-php - build-http - build-prometheus-exporter-file - supported-alpine-versions - supported-php-versions + - supported-platforms - php-type-matrix - runs-on: ubuntu-latest + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: alpine: ${{ fromJson(needs.supported-alpine-versions.outputs.alpine) }} php: ${{ fromJson(needs.supported-php-versions.outputs.php) }} type: ${{ fromJson(needs.php-type-matrix.outputs.type) }} - include: - - php: "7.1" - alpine: "3.10" - type: cli - - php: "7.1" - alpine: "3.10" - type: fpm - - php: "8.0" - alpine: "3.14" - type: cli - - php: "8.0" - alpine: "3.14" - type: fpm - - php: "8.0" - alpine: "3.15" - type: cli - - php: "8.0" - alpine: "3.15" - type: fpm - - php: "8.0" - alpine: "3.16" - type: cli - - php: "8.0" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.15" - type: cli - - php: "8.1" - alpine: "3.15" - type: fpm - - php: "8.1" - alpine: "3.16" - type: cli - - php: "8.1" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.17" - type: cli - - php: "8.1" - alpine: "3.17" - type: fpm - - php: "8.2" - alpine: "3.17" - type: "cli" - - php: "8.2" - alpine: "3.17" - type: "fpm" - - php: "8.2" - alpine: "3.19" - type: "cli" - - php: "8.2" - alpine: "3.19" - type: "fpm" - - php: "8.2" - alpine: "3.22" - type: "cli" - - php: "8.2" - alpine: "3.22" - type: "fpm" - - php: "8.3" - alpine: "3.19" - type: "cli" - - php: "8.3" - alpine: "3.19" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "fpm" + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - name: Download Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }} + name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }}-${{ env.PLATFORM_PAIR }} path: ./tmp - run: docker load --input ./tmp/image*.tar + - run: mv ./tmp/build-${{ matrix.type }}-${{ env.PLATFORM_PAIR }}.tags ./tmp/build-${{ matrix.type }}.tags - run: make test-${{ matrix.type }} test-http: - name: Functionaly test nginx ${{ matrix.nginx }} with PHP FPM ${{ matrix.php }} on Alpine ${{ matrix.alpine }} + name: Functionaly test nginx ${{ matrix.nginx }} with PHP FPM ${{ matrix.php }} on Alpine ${{ matrix.alpine }} (${{ matrix.platform }}) needs: - build-http - build-php @@ -530,51 +344,70 @@ jobs: - supported-alpine-versions - supported-nginx-versions - supported-php-versions - runs-on: ubuntu-latest + - supported-platforms + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false matrix: alpine: ${{ fromJson(needs.supported-alpine-versions.outputs.alpine) }} nginx: ${{ fromJson(needs.supported-nginx-versions.outputs.nginx) }} php: ${{ fromJson(needs.supported-php-versions.outputs.php) }} + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - name: Download PHP Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-fpm-${{ matrix.php }}-${{ matrix.alpine }} + name: docker-image-fpm-${{ matrix.php }}-${{ matrix.alpine }}-${{ env.PLATFORM_PAIR }} path: ./tmp - name: Download nginx Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-http-${{ matrix.nginx }} + name: docker-image-http-${{ matrix.nginx }}-${{ env.PLATFORM_PAIR }} path: ./tmp - - run: docker load --input ./tmp/image-fpm-${{ matrix.php }}-${{ matrix.alpine }}.tar - - run: docker load --input ./tmp/image-http-${{ matrix.nginx }}.tar + - run: docker load --input ./tmp/image-fpm-${{ matrix.php }}-${{ matrix.alpine }}-${{ env.PLATFORM_PAIR }}.tar + - run: docker load --input ./tmp/image-http-${{ matrix.nginx }}-${{ env.PLATFORM_PAIR }}.tar - run: sudo chown -R 1000:1000 ./test/functional/web/tmp/ # Ensure we have the same uid:gid as our `app` docker user shell: bash + - run: | + mv ./tmp/build-http-${{ env.PLATFORM_PAIR }}.tags ./tmp/build-http.tags + mv ./tmp/build-fpm-${{ env.PLATFORM_PAIR }}.tags ./tmp/build-fpm.tags - run: make test-http - run: make test-http-e2e test-prometheus-exporter-file: - name: Functionaly test prometheus-exporter-file + name: Functionaly test prometheus-exporter-file (${{ matrix.platform }}) needs: - build-http - build-php - build-prometheus-exporter-file - supported-nginx-versions - runs-on: ubuntu-latest + - supported-platforms + runs-on: ${{ contains(matrix.platform, 'arm') && 'ubuntu-24.04-arm' || 'ubuntu-24.04' }} strategy: fail-fast: false + matrix: + platform: ${{ fromJson(needs.supported-platforms.outputs.platform) }} steps: - - uses: actions/checkout@v2 + - name: Prepare + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + printf "PLATFORM_ARCH=%s" $(echo "${{ matrix.platform }}" | cut -d "/" -f 2) >> $GITHUB_ENV + - uses: actions/checkout@v5 - name: Download nginx Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-prometheus-exporter-file + name: docker-image-prometheus-exporter-file-${{ env.PLATFORM_PAIR }} path: ./tmp - - run: docker load --input ./tmp/image-prometheus-exporter-file.tar + - run: docker load --input ./tmp/image-prometheus-exporter-file-${{ env.PLATFORM_PAIR }}.tar - run: sudo chown -R 1000:1000 ./test/functional/web/tmp/ # Ensure we have the same uid:gid as our `app` docker user shell: bash + - run: mv ./tmp/build-prometheus-exporter-file-${{ env.PLATFORM_PAIR }}.tags ./tmp/build-prometheus-exporter-file.tags - run: make test-prometheus-exporter-file-e2e check-mark: # This is our required step, pay extra attention when this step is changed for what ever reason name: ✔️ @@ -598,21 +431,57 @@ jobs: - scan-vulnerability-http - scan-vulnerability-php - scan-vulnerability-prometheus-exporter-file + - supported-platforms + - check-mark runs-on: ubuntu-latest + services: + registry: + image: registry:3 + ports: + - 5000:5000 strategy: fail-fast: false steps: - - uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + driver-opts: network=host + - uses: actions/checkout@v5 - name: Download Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-prometheus-exporter-file + pattern: docker-image-prometheus-exporter-file-* path: ./tmp - - run: docker load --input ./tmp/image*.tar - - run: make ci-docker-login push-prometheus-exporter-file + merge-multiple: true + - run: cat ./tmp/build-*.tags > ./tmp/build.tags + - run: | + for f in ./tmp/image-*.tar; do + docker load --input $f + done + - run: | + xargs -I % docker tag "%" "localhost:5000/%" < ./tmp/build.tags + xargs -I % docker push "localhost:5000/%" < ./tmp/build.tags + - name: Collect non-Arch suffixed tags + run: | + php -r 'echo implode( PHP_EOL, array_values( array_filter( array_unique( array_map( static function (string $tag) use ($argv): string {$tag = trim($tag); foreach ( explode(",", getenv("ARCHS")) as $platform) { [$os, $arch] = explode("/", $platform); $tag = str_replace("-" . $os . "-" . $arch, "", $tag); $tag = str_replace("${{ env.DOCKER_IMAGE }}:", "", $tag); } return $tag; }, file("./tmp/build.tags") ) ), static fn (string $tag): bool => strlen($tag) > 0) ) );' > ./tmp/tags-to-push.list + cat ./tmp/tags-to-push.list + env: + ARCHS: ${{ join(fromJson(needs.supported-platforms.outputs.platform), ',') }} + - name: Create merge Dockerfiles + run: | + cat ./tmp/tags-to-push.list | xargs -I % sh -c 'echo "FROM localhost:5000/${{ env.DOCKER_IMAGE }}:%-\${TARGETOS}-\${TARGETARCH}" >> ./tmp/docker-file-%' + cat ./tmp/docker-file-* + ls -lasth ./tmp/docker-file-* + - run: make ci-docker-login env: CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + - name: Push all images to registries + run: | + cat ./tmp/tags-to-push.list | xargs -I % docker buildx build -f ./tmp/docker-file-% -t ${{ env.DOCKER_IMAGE }}:% --platform=${{ join(fromJson(needs.supported-platforms.outputs.platform), ',') }} --push . push-http: name: Push nginx ${{ matrix.nginx }} if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/master' @@ -624,23 +493,60 @@ jobs: - scan-vulnerability-php - scan-vulnerability-prometheus-exporter-file - supported-nginx-versions + - supported-platforms + - check-mark runs-on: ubuntu-latest + services: + registry: + image: registry:3 + ports: + - 5000:5000 strategy: fail-fast: false matrix: nginx: ${{ fromJson(needs.supported-nginx-versions.outputs.nginx) }} steps: - - uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + driver-opts: network=host + - uses: actions/checkout@v5 - name: Download Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-http-${{ matrix.nginx }} + pattern: docker-image-http-${{ matrix.nginx }}-* path: ./tmp - - run: docker load --input ./tmp/image*.tar - - run: make ci-docker-login push-http + merge-multiple: true + - run: cat ./tmp/build-*.tags > ./tmp/build.tags + - run: | + for f in ./tmp/image-*.tar; do + docker load --input $f + done + - run: | + xargs -I % docker tag "%" "localhost:5000/%" < ./tmp/build.tags + xargs -I % docker push "localhost:5000/%" < ./tmp/build.tags + - name: Collect non-Arch suffixed tags + run: | + php -r 'echo implode( PHP_EOL, array_values( array_filter( array_unique( array_map( static function (string $tag) use ($argv): string {$tag = trim($tag); foreach ( explode(",", getenv("ARCHS")) as $platform) { [$os, $arch] = explode("/", $platform); $tag = str_replace("-" . $os . "-" . $arch, "", $tag); $tag = str_replace("${{ env.DOCKER_IMAGE }}:", "", $tag); } return $tag; }, file("./tmp/build.tags") ) ), static fn (string $tag): bool => strlen($tag) > 0) ) );' > ./tmp/tags-to-push.list + cat ./tmp/tags-to-push.list + env: + ARCHS: ${{ join(fromJson(needs.supported-platforms.outputs.platform), ',') }} + - name: Create merge Dockerfiles + run: | + cat ./tmp/tags-to-push.list | xargs -I % sh -c 'echo "FROM localhost:5000/${{ env.DOCKER_IMAGE }}:%-\${TARGETOS}-\${TARGETARCH}" >> ./tmp/docker-file-%' + cat ./tmp/docker-file-* + ls -lasth ./tmp/docker-file-* + - run: make ci-docker-login env: CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + - name: Push all images to registries + run: | + cat ./tmp/tags-to-push.list | xargs -I % docker buildx build -f ./tmp/docker-file-% -t ${{ env.DOCKER_IMAGE }}:% --platform=${{ join(fromJson(needs.supported-platforms.outputs.platform), ',') }} --push . + push-php: name: Push PHP ${{ matrix.php }} for ${{ matrix.type }} on Alpine ${{ matrix.alpine }} if: (github.event_name == 'push' || github.event_name == 'schedule') && github.ref == 'refs/heads/master' @@ -653,102 +559,59 @@ jobs: - scan-vulnerability-prometheus-exporter-file - supported-alpine-versions - supported-php-versions + - supported-platforms - php-type-matrix + - check-mark runs-on: ubuntu-latest + services: + registry: + image: registry:3 + ports: + - 5000:5000 strategy: fail-fast: false matrix: alpine: ${{ fromJson(needs.supported-alpine-versions.outputs.alpine) }} php: ${{ fromJson(needs.supported-php-versions.outputs.php) }} type: ${{ fromJson(needs.php-type-matrix.outputs.type) }} - include: - - php: "7.1" - alpine: "3.10" - type: cli - - php: "7.1" - alpine: "3.10" - type: fpm - - php: "8.0" - alpine: "3.14" - type: cli - - php: "8.0" - alpine: "3.14" - type: fpm - - php: "8.0" - alpine: "3.15" - type: cli - - php: "8.0" - alpine: "3.15" - type: fpm - - php: "8.0" - alpine: "3.16" - type: cli - - php: "8.0" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.15" - type: cli - - php: "8.1" - alpine: "3.15" - type: fpm - - php: "8.1" - alpine: "3.16" - type: cli - - php: "8.1" - alpine: "3.16" - type: fpm - - php: "8.1" - alpine: "3.17" - type: cli - - php: "8.1" - alpine: "3.17" - type: fpm - - php: "8.2" - alpine: "3.17" - type: "cli" - - php: "8.2" - alpine: "3.17" - type: "fpm" - - php: "8.2" - alpine: "3.19" - type: "cli" - - php: "8.2" - alpine: "3.19" - type: "fpm" - - php: "8.2" - alpine: "3.22" - type: "cli" - - php: "8.2" - alpine: "3.22" - type: "fpm" - - php: "8.3" - alpine: "3.19" - type: "cli" - - php: "8.3" - alpine: "3.19" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "fpm" - - php: "8.3" - alpine: "3.20" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "cli" - - php: "8.4" - alpine: "3.22" - type: "fpm" steps: - - uses: actions/checkout@v2 + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + driver-opts: network=host + - uses: actions/checkout@v5 - name: Download Images uses: actions/download-artifact@v4.1.7 with: - name: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }} + pattern: docker-image-${{ matrix.type }}-${{ matrix.php }}-${{ matrix.alpine }}-* path: ./tmp - - run: docker load --input ./tmp/image*.tar - - run: make ci-docker-login push-${{ matrix.type }} + merge-multiple: true + - run: cat ./tmp/build-*.tags > ./tmp/build.tags + - run: | + for f in ./tmp/image-*.tar; do + docker load --input $f + done + - run: | + xargs -I % docker tag "%" "localhost:5000/%" < ./tmp/build.tags + xargs -I % docker push "localhost:5000/%" < ./tmp/build.tags + - name: Collect non-Arch suffixed tags + run: | + php -r 'echo implode( PHP_EOL, array_values( array_filter( array_unique( array_map( static function (string $tag) use ($argv): string {$tag = trim($tag); foreach ( explode(",", getenv("ARCHS")) as $platform) { [$os, $arch] = explode("/", $platform); $tag = str_replace("-" . $os . "-" . $arch, "", $tag); $tag = str_replace("${{ env.DOCKER_IMAGE }}:", "", $tag); } return $tag; }, file("./tmp/build.tags") ) ), static fn (string $tag): bool => strlen($tag) > 0) ) );' > ./tmp/tags-to-push.list + cat ./tmp/tags-to-push.list + env: + ARCHS: ${{ join(fromJson(needs.supported-platforms.outputs.platform), ',') }} + - name: Create merge Dockerfiles + run: | + cat ./tmp/tags-to-push.list | xargs -I % sh -c 'echo "FROM localhost:5000/${{ env.DOCKER_IMAGE }}:%-\${TARGETOS}-\${TARGETARCH}" >> ./tmp/docker-file-%' + cat ./tmp/docker-file-* + ls -lasth ./tmp/docker-file-* + - run: make ci-docker-login env: CONTAINER_REGISTRY_USERNAME: ${{ secrets.CONTAINER_REGISTRY_USERNAME }} CONTAINER_REGISTRY_PASSWORD: ${{ secrets.CONTAINER_REGISTRY_PASSWORD }} + - name: Push all images to registries + run: | + cat ./tmp/tags-to-push.list | xargs -I % docker buildx build -f ./tmp/docker-file-% -t ${{ env.DOCKER_IMAGE }}:% --platform=${{ join(fromJson(needs.supported-platforms.outputs.platform), ',') }} --push . diff --git a/Dockerfile-cli b/Dockerfile-cli index e9c3fdcc..cc94abbf 100644 --- a/Dockerfile-cli +++ b/Dockerfile-cli @@ -1,5 +1,7 @@ # syntax=docker/dockerfile:experimental FROM php:7.2-cli-alpine3.7 as cli +ARG TARGETOS +ARG TARGETARCH # Add usabilla user and group RUN set -x \ @@ -15,6 +17,7 @@ COPY src/php/utils/docker/ /usr/local/bin/ # Install PHP extensions # hadolint ignore=DL4006 RUN set -x \ + && apk upgrade --no-cache \ # Install curl-dev in order to address the curl binary issue in some Alpine versions && apk add --no-cache curl-dev \ # Adding sodium purely for the 7.1 image, it's already in 7.2 and up: https://www.php.net/manual/en/sodium.installation.php \ @@ -31,9 +34,6 @@ RUN set -x \ && docker-php-source-tarball clean && rm /usr/local/bin/php-cgi && rm /usr/local/bin/phpdbg && rm -rf /tmp/pear ~/.pearrc \ && apk del .phpize-deps \ - # Patch CVE-2018-14618 (curl), CVE-2018-16842 (libxml2), CVE-2019-11068 (libxslt) - && apk upgrade --no-cache curl libxml2 libxslt \ - # Create a symlink to the recommended production configuration # ref: https://github.com/docker-library/docs/tree/master/php#configuration && ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini diff --git a/Dockerfile-fpm b/Dockerfile-fpm index f6688846..947fc744 100644 --- a/Dockerfile-fpm +++ b/Dockerfile-fpm @@ -1,5 +1,7 @@ # syntax=docker/dockerfile:experimental FROM php:7.2-fpm-alpine3.7 as fpm +ARG TARGETOS +ARG TARGETARCH ENV FCGI_CONNECT=/var/run/php-fpm.sock ENV PHP_FPM_PM=dynamic @@ -26,6 +28,7 @@ COPY src/php/utils/install-* /usr/local/bin/ # Install PHP extensions # hadolint ignore=DL4006 RUN set -x \ + && apk upgrade --no-cache \ # Install curl-dev in order to address the curl binary issue in some Alpine versions && apk add --no-cache curl-dev \ # Adding sodium purely for the 7.1 image, it's already in 7.2 and up: https://www.php.net/manual/en/sodium.installation.php \ @@ -43,9 +46,6 @@ RUN set -x \ && apk del .phpize-deps \ && apk add --no-cache fcgi \ - # Patch CVE-2018-14618 (curl), CVE-2018-16842 (libxml2), CVE-2019-11068 (libxslt) - && apk upgrade --no-cache curl libxml2 libxslt \ - # Create a symlink to the recommended production configuration # ref: https://github.com/docker-library/docs/tree/master/php#configuration && ln -s $PHP_INI_DIR/php.ini-production $PHP_INI_DIR/php.ini diff --git a/Dockerfile-http b/Dockerfile-http index f758ca1c..3b1c12aa 100644 --- a/Dockerfile-http +++ b/Dockerfile-http @@ -1,4 +1,4 @@ -FROM nginx:1.15-alpine as http +FROM nginx:1.15-alpine AS http # Add usabilla user and group RUN set -x \ @@ -21,8 +21,8 @@ ENV NGINX_LARGE_CLIENT_HEADER_BUFFERS="4 8k" ENV NGINX_CORS_ENABLE=false ENV NGINX_CORS_ALLOW_ORIGIN="*" -# Patch gCVE-2019-11068 (libxslt) -RUN apk upgrade --no-cache libxslt +RUN set -x \ + && apk upgrade --no-cache # Nginx helper scripts COPY src/http/nginx/docker-nginx-* /usr/local/bin/ @@ -37,6 +37,6 @@ CMD ["docker-nginx-entrypoint"] # this can be overriden in the child images HEALTHCHECK NONE -FROM http as http-dev +FROM http AS http-dev ENV NGINX_EXPOSE_VERSION=on diff --git a/Makefile b/Makefile index bbf92aeb..88cb68da 100644 --- a/Makefile +++ b/Makefile @@ -52,7 +52,7 @@ build-http: clean-tags # Adding arbitrary version 1.0 in order to make sure if we break compatibility we have to up it build-prometheus-exporter-file: BUILDINGIMAGE=prometheus-exporter-file build-prometheus-exporter-file: clean-tags - ./build-prometheus-exporter-file.sh 1.18 prometheus-exporter-file1.0 prometheus-exporter-file1 + ./build-prometheus-exporter-file.sh 1.29 prometheus-exporter-file1.0 prometheus-exporter-file1 .NOTPARALLEL: clean-tags clean-tags: @@ -103,8 +103,4 @@ test-prometheus-exporter-file-e2e: ./tmp/build-prometheus-exporter-file.tags xargs -I % ./test-prometheus-exporter-file-e2e.sh % < ./tmp/build-prometheus-exporter-file.tags scan-vulnerability: - docker compose -f test/security/docker-compose.yml -p clair-ci up -d - RETRIES=0 && while ! wget -T 10 -q -O /dev/null http://localhost:6060/v1/namespaces ; do sleep 1 ; echo -n "." ; if [ $${RETRIES} -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; RETRIES=$$(($${RETRIES}+1)) ; done - mkdir -p ./tmp/clair/usabillabv - cat ./tmp/build-*.tags | xargs -I % sh -c 'clair-scanner --ip 172.17.0.1 -r "./tmp/clair/%.json" -l ./tmp/clair/clair.log % || echo "% is vulnerable"' - docker compose -f test/security/docker-compose.yml -p clair-ci down + cat ./tmp/build-*.tags | xargs -I % sh -c 'docker run -v /tmp/trivy:/var/lib/trivy -v /var/run/docker.sock:/var/run/docker.sock -t aquasec/trivy:latest --cache-dir /var/lib/trivy image --skip-files "/usr/local/bin/shush" --exit-code 1 --no-progress % || (echo "% is vulnerable" && exit 1)' diff --git a/build-http.sh b/build-http.sh index f318a92b..d542686b 100755 --- a/build-http.sh +++ b/build-http.sh @@ -15,22 +15,32 @@ declare -r IMAGE_ORIGINAL_TAG="nginx:1.[0-9][0-9]?-alpine" declare -r IMAGE_TAG="nginx:${VERSION_NGINX}-alpine" declare -r USABILLA_TAG_PREFIX="usabillabv/php" -declare -r USABILLA_TAG="${USABILLA_TAG_PREFIX}:nginx${VERSION_NGINX}" -declare -r USABILLA_TAG_DEV="${USABILLA_TAG}-dev" - -TAG_FILE="./tmp/build-${IMAGE}.tags" - +if [[ ! -v DOCKER_BUILD_PLATFORM ]]; then + declare -r DOCKER_BUILD_FLAGS="" + declare -r USABILLA_TAG_SUFFIX="" +else + declare -r DOCKER_BUILD_FLAGS="--platform=${DOCKER_BUILD_PLATFORM}" + # shellcheck disable=SC2155 + declare -r USABILLA_TAG_SUFFIX="-${DOCKER_BUILD_PLATFORM//\//-}" +fi +declare -r USABILLA_TAG="${USABILLA_TAG_PREFIX}:nginx${VERSION_NGINX}${USABILLA_TAG_SUFFIX}" +declare -r USABILLA_TAG_DEV="${USABILLA_TAG_PREFIX}:nginx${VERSION_NGINX}-dev${USABILLA_TAG_SUFFIX}" + +declare -r TAG_FILE="./tmp/build-${IMAGE}${USABILLA_TAG_SUFFIX}.tags" + +# shellcheck disable=SC2086 sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${IMAGE}" | docker build --pull -t "${USABILLA_TAG}" \ - --build-arg=NGINX_VHOST_TEMPLATE=php-fpm --target="${IMAGE}" -f - . \ + --build-arg=NGINX_VHOST_TEMPLATE=php-fpm --target="${IMAGE}" ${DOCKER_BUILD_FLAGS} -f - . \ && echo "${USABILLA_TAG}" >> "${TAG_FILE}" +# shellcheck disable=SC2086 sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${IMAGE}" | docker build --pull -t "${USABILLA_TAG_DEV}" \ - --build-arg=NGINX_VHOST_TEMPLATE=php-fpm --target="${IMAGE}-dev" -f - . \ + --build-arg=NGINX_VHOST_TEMPLATE=php-fpm --target="${IMAGE}-dev" ${DOCKER_BUILD_FLAGS} -f - . \ && echo "$USABILLA_TAG_DEV" >> "${TAG_FILE}" for IMAGE_EXTRA_TAG in "${@:2}" do declare NEW_TAG="${USABILLA_TAG_PREFIX}:${IMAGE_EXTRA_TAG}" - docker tag "${USABILLA_TAG}" "${NEW_TAG}" && echo "${NEW_TAG}" >> "${TAG_FILE}" - docker tag "${USABILLA_TAG_DEV}" "${NEW_TAG}-dev" && echo "${NEW_TAG}-dev" >> "${TAG_FILE}" + docker tag "${USABILLA_TAG}" "${NEW_TAG}${USABILLA_TAG_SUFFIX}" && echo "${NEW_TAG}${USABILLA_TAG_SUFFIX}" >> "${TAG_FILE}" + docker tag "${USABILLA_TAG_DEV}" "${NEW_TAG}-dev${USABILLA_TAG_SUFFIX}" && echo "${NEW_TAG}-dev${USABILLA_TAG_SUFFIX}" >> "${TAG_FILE}" done diff --git a/build-php.sh b/build-php.sh index fe7dea19..15fb02ff 100755 --- a/build-php.sh +++ b/build-php.sh @@ -16,13 +16,24 @@ declare -r VERSION_ALPINE=$3 declare -r IMAGE_ORIGINAL_TAG="7.[0-9]-${IMAGE}-alpine3.[0-9]" declare -r IMAGE_TAG="${VERSION_PHP}-${IMAGE}-alpine${VERSION_ALPINE}" -declare -r USABILLA_TAG="usabillabv/php:${VERSION_PHP}-${IMAGE}-alpine${VERSION_ALPINE}" -declare -r USABILLA_TAG_DEV="${USABILLA_TAG}-dev" - -declare -r TAG_FILE="./tmp/build-${IMAGE}.tags" - -sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${IMAGE}" | docker build --pull -t "${USABILLA_TAG}" --target="${IMAGE}" -f - . \ +if [[ ! -v DOCKER_BUILD_PLATFORM ]]; then + declare -r DOCKER_BUILD_FLAGS="" + declare -r USABILLA_TAG_SUFFIX="" +else + declare -r DOCKER_BUILD_FLAGS="--platform=${DOCKER_BUILD_PLATFORM}" + # shellcheck disable=SC2155 + declare -r USABILLA_TAG_SUFFIX="-${DOCKER_BUILD_PLATFORM//\//-}" +fi +declare -r USABILLA_TAG_PREFIX="usabillabv/php:${VERSION_PHP}-${IMAGE}-alpine${VERSION_ALPINE}" +declare -r USABILLA_TAG="${USABILLA_TAG_PREFIX}${USABILLA_TAG_SUFFIX}" +declare -r USABILLA_TAG_DEV="${USABILLA_TAG_PREFIX}-dev${USABILLA_TAG_SUFFIX}" + +declare -r TAG_FILE="./tmp/build-${IMAGE}${USABILLA_TAG_SUFFIX}.tags" + +# shellcheck disable=SC2086 +sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${IMAGE}" | docker build --pull -t "${USABILLA_TAG}" --target="${IMAGE}" ${DOCKER_BUILD_FLAGS} -f - . \ && echo "$USABILLA_TAG" >> "$TAG_FILE" -sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${IMAGE}" | docker build --pull -t "${USABILLA_TAG_DEV}" --target="${IMAGE}-dev" -f - . \ +# shellcheck disable=SC2086 +sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${IMAGE}" | docker build --pull -t "${USABILLA_TAG_DEV}" --target="${IMAGE}-dev" ${DOCKER_BUILD_FLAGS} -f - . \ && echo "$USABILLA_TAG_DEV" >> "$TAG_FILE" diff --git a/build-prometheus-exporter-file.sh b/build-prometheus-exporter-file.sh index 1d84ac6e..80cadafd 100755 --- a/build-prometheus-exporter-file.sh +++ b/build-prometheus-exporter-file.sh @@ -17,16 +17,25 @@ declare -r IMAGE_ORIGINAL_TAG="nginx:1.[0-9][0-9]?-alpine" declare -r IMAGE_TAG="nginx:${VERSION_NGINX}-alpine" declare -r USABILLA_TAG_PREFIX="usabillabv/php" -declare -r USABILLA_TAG="${USABILLA_TAG_PREFIX}:${IMAGE}" - -TAG_FILE="./tmp/build-${IMAGE}.tags" - +if [[ ! -v DOCKER_BUILD_PLATFORM ]]; then + declare -r DOCKER_BUILD_FLAGS="" + declare -r USABILLA_TAG_SUFFIX="" +else + declare -r DOCKER_BUILD_FLAGS="--platform=${DOCKER_BUILD_PLATFORM}" + # shellcheck disable=SC2155 + declare -r USABILLA_TAG_SUFFIX="-${DOCKER_BUILD_PLATFORM//\//-}" +fi +declare -r USABILLA_TAG="${USABILLA_TAG_PREFIX}:${IMAGE}${USABILLA_TAG_SUFFIX}" + +declare -r TAG_FILE="./tmp/build-${IMAGE}${USABILLA_TAG_SUFFIX}.tags" + +# shellcheck disable=SC2086 sed -E "s/${IMAGE_ORIGINAL_TAG}/${IMAGE_TAG}/g" "Dockerfile-${DOCKER_FILE}" | docker build --pull -t "${USABILLA_TAG}" \ - --build-arg=NGINX_VHOST_TEMPLATE=prometheus-exporter-file --target="http" -f - . \ + --build-arg=NGINX_VHOST_TEMPLATE=prometheus-exporter-file --target="http" ${DOCKER_BUILD_FLAGS} -f - . \ && echo "${USABILLA_TAG}" >> "${TAG_FILE}" for USABILLA_TAG_EXTRA in "${@:2}" do - docker tag "${USABILLA_TAG}" "${USABILLA_TAG_PREFIX}:${USABILLA_TAG_EXTRA}" \ - && echo "${USABILLA_TAG_PREFIX}:${USABILLA_TAG_EXTRA}" >> "${TAG_FILE}" + docker tag "${USABILLA_TAG}" "${USABILLA_TAG_PREFIX}:${USABILLA_TAG_EXTRA}${USABILLA_TAG_SUFFIX}" \ + && echo "${USABILLA_TAG_PREFIX}:${USABILLA_TAG_EXTRA}${USABILLA_TAG_SUFFIX}" >> "${TAG_FILE}" done diff --git a/src/php/utils/install-dumb-init b/src/php/utils/install-dumb-init index ea802768..e664e918 100755 --- a/src/php/utils/install-dumb-init +++ b/src/php/utils/install-dumb-init @@ -4,7 +4,7 @@ set -xeu VERSION="1.2.2" -curl -sL -o /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v"$VERSION"/dumb-init_"$VERSION"_amd64 +curl -sL -o /usr/local/bin/dumb-init https://github.com/Yelp/dumb-init/releases/download/v"$VERSION"/dumb-init_"$VERSION"_"${TARGETARCH}" chmod +x /usr/local/bin/dumb-init diff --git a/src/php/utils/install-shush b/src/php/utils/install-shush index 84aee460..5872e40f 100755 --- a/src/php/utils/install-shush +++ b/src/php/utils/install-shush @@ -2,9 +2,9 @@ set -xe -curl -sL -o /usr/local/bin/shush https://github.com/realestate-com-au/shush/releases/download/v1.5.0/shush_linux_amd64 +curl -sL -o /usr/local/bin/shush "https://github.com/realestate-com-au/shush/releases/download/v1.5.5/shush_linux_${TARGETARCH}" -echo "cdec941dc5f45dda2d981169aa1845540d2c5bf98bfd1d8a85deaa6a6a43a4d1 /usr/local/bin/shush" | sha256sum -c +(echo "d0e091405a18b6d11a65ea1d7449802c0cbac51971031897089d038e6f7cc750 /usr/local/bin/shush" | sha256sum -c) || (echo "138af0f1eec3af50176d542fead8824c3ca0f6ba27a4a50e1db8af5959a13116 /usr/local/bin/shush" | sha256sum -c) chmod +x /usr/local/bin/shush diff --git a/test-cli.sh b/test-cli.sh index 97515dec..32561a4c 100755 --- a/test-cli.sh +++ b/test-cli.sh @@ -13,7 +13,7 @@ declare -r DOCKER_TAG="$1" declare TEST_SUITE -if [[ $DOCKER_TAG == *"-dev" ]]; then +if [[ $DOCKER_TAG == *"-dev"* ]]; then TEST_SUITE="php or php_cli or php_dev" else TEST_SUITE="php or php_cli or php_no_dev and not php_dev" @@ -36,6 +36,6 @@ docker run --rm -t \ -v "$(pwd)/test:/tests" \ -v "$(pwd)/tmp/test-results:/results" \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ - renatomefi/docker-testinfra:5 \ + ghcr.io/wyrihaximusnet/testinfra:2025.03.31 \ -m "$TEST_SUITE" --junitxml="/results/php-cli-$DOCKER_TAG.xml" \ --verbose --hosts="docker://$DOCKER_CONTAINER" diff --git a/test-fpm.sh b/test-fpm.sh index fb0c3ffa..9faad238 100755 --- a/test-fpm.sh +++ b/test-fpm.sh @@ -13,7 +13,7 @@ declare -r DOCKER_TAG="$1" declare TEST_SUITE -if [[ $DOCKER_TAG == *"-dev" ]]; then +if [[ $DOCKER_TAG == *"-dev"* ]]; then TEST_SUITE="php or php_fpm or php_dev" else VERSION_SUITE=$(echo "${DOCKER_TAG}" | grep -P ':\d.\d-' -o | sed 's/[^0-9]*//g') @@ -37,6 +37,6 @@ docker run --rm -t \ -v "$(pwd)/test:/tests" \ -v "$(pwd)/tmp/test-results:/results" \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ - renatomefi/docker-testinfra:5 \ + ghcr.io/wyrihaximusnet/testinfra:2025.03.31 \ -m "$TEST_SUITE" --junitxml="/results/php-fpm-$DOCKER_TAG.xml" \ --verbose --hosts="docker://$DOCKER_CONTAINER" diff --git a/test-http-e2e.sh b/test-http-e2e.sh index edae8845..8a8cd96a 100755 --- a/test-http-e2e.sh +++ b/test-http-e2e.sh @@ -18,6 +18,6 @@ docker run --net="host" --rm -t \ -v "$(pwd)/test/e2e:/tests" \ -v "$(pwd)/tmp/test-results:/results" \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ - renatomefi/docker-testinfra:5 \ + ghcr.io/wyrihaximusnet/testinfra:2025.03.31 \ -m "$TEST_SUITE" --junitxml="/results/http-e2e-$DOCKER_NGINX_TAG.xml" \ --verbose --tag="$1" diff --git a/test-http.sh b/test-http.sh index 809987cc..7d5b8a5d 100755 --- a/test-http.sh +++ b/test-http.sh @@ -36,6 +36,6 @@ docker run --rm -t \ -v "$(pwd)/test:/tests" \ -v "$(pwd)/tmp/test-results:/results" \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ - renatomefi/docker-testinfra:5 \ + ghcr.io/wyrihaximusnet/testinfra:2025.03.31 \ -m "$TEST_SUITE" --junitxml="/results/http-$DOCKER_NGINX_TAG.xml" \ --verbose --hosts="docker://$DOCKER_NGINX_CONTAINER" diff --git a/test-prometheus-exporter-file-e2e.sh b/test-prometheus-exporter-file-e2e.sh index b6fd1351..3343e510 100755 --- a/test-prometheus-exporter-file-e2e.sh +++ b/test-prometheus-exporter-file-e2e.sh @@ -18,6 +18,6 @@ docker run --net="host" --rm -t \ -v "$(pwd)/test/e2e:/tests" \ -v "$(pwd)/tmp/test-results:/results" \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ - renatomefi/docker-testinfra:5 \ + ghcr.io/wyrihaximusnet/testinfra:2025.03.31 \ -m "$TEST_SUITE" --junitxml="/results/http-e2e-$DOCKER_TAG.xml" \ --verbose --tag="$1" diff --git a/test/e2e/test_nginx_entrypoint.py b/test/e2e/test_nginx_entrypoint.py index 1deb0c63..c812da7e 100644 --- a/test/e2e/test_nginx_entrypoint.py +++ b/test/e2e/test_nginx_entrypoint.py @@ -1,4 +1,5 @@ import pytest +import time @pytest.mark.nginx_e2e @@ -22,6 +23,10 @@ def test_nginx_sigterm_handling(host, container): @pytest.mark.nginx_e2e @pytest.mark.parametrize('container', [{'env': {'NGINX_PORT': '5556'}, 'port': '5556'}], indirect=True) def test_nginx_can_host_different_ports(host, container): + start = time.time() + while host.run('docker exec -t {} sh -c "wget http://127.0.0.1:5556/"'.format(container)).rc is not 1 and time.time() - start < 13: + time.sleep(1) + wget_custom_port = host.run('docker exec -t {} sh -c "wget http://127.0.0.1:5556/"'.format(container)) assert wget_custom_port.rc is 1 assert u'502 Bad Gateway' in wget_custom_port.stdout diff --git a/test/e2e/test_nginx_logs.py b/test/e2e/test_nginx_logs.py index 11fa7e5c..abb60a75 100644 --- a/test/e2e/test_nginx_logs.py +++ b/test/e2e/test_nginx_logs.py @@ -1,10 +1,17 @@ import pytest +import time @pytest.mark.nginx_e2e def test_nginx_logs_to_stdout_and_stderr(host, container): nginx_port = host.check_output("docker inspect " + container + " --format '{{ (index (index .NetworkSettings.Ports \"80/tcp\") 0).HostPort }}'") + host.run('wget -O /dev/null -S 127.0.0.1:{}/not-valid'.format(nginx_port)) + start = time.time() + while 'GET /not-valid' not in host.run('docker logs {}'.format(container)).stdout and time.time() - start < 13: + time.sleep(1) + host.run('wget -O /dev/null -S 127.0.0.1:{}/not-valid'.format(nginx_port)) + wget = host.run('wget -O /dev/null -S 127.0.0.1:{}/invalid'.format(nginx_port)) assert wget.rc is not 0 diff --git a/test/security/docker-compose.yml b/test/security/docker-compose.yml deleted file mode 100644 index b0781eb4..00000000 --- a/test/security/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: '3.2' -services: - postgres: - container_name: clair_postgres - # This image provides a nightly build with updated vulnerability databases - # once setting up clair from scratch can take up to 30 minutes - image: arminc/clair-db:latest - restart: unless-stopped - environment: - POSTGRES_PASSWORD: password - - clair: - container_name: clair_clair - image: arminc/clair-local-scan:v2.0.4 - restart: unless-stopped - depends_on: - - postgres - ports: - - "6060-6061:6060-6061" - links: - - postgres