-
Notifications
You must be signed in to change notification settings - Fork 1.4k
fix(docker): multi-arch image build (amd64+arm64) -- closes #223 #445
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
TheAuditorTool
wants to merge
4
commits into
OWASP-Benchmark:master
Choose a base branch
from
TheAuditorTool:fix/multi-arch-docker
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
c68a62b
fix(docker): multi-arch image build (amd64+arm64) -- closes #223
TheAuditorTool e721461
fix(docker): use ubuntu:latest per maintainer review
TheAuditorTool 6194942
fix(docker): correct Dockerfile path and image tag in VMs scripts
TheAuditorTool 7284a47
docs(docker): add multi-arch activation guide
TheAuditorTool File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| # ------------------------------------------------------------------ | ||
| # INACTIVE BY DEFAULT -- manual trigger only (workflow_dispatch). | ||
| # | ||
| # This workflow builds and publishes a multi-architecture Docker image | ||
| # (linux/amd64 + linux/arm64) to Docker Hub. | ||
| # | ||
| # TO ACTIVATE: | ||
| # 1. Add two repository secrets (Settings > Secrets and variables > Actions): | ||
| # DOCKERHUB_USERNAME - your Docker Hub username | ||
| # DOCKERHUB_TOKEN - a Docker Hub access token (not your password) | ||
| # 2. Optionally add automatic triggers by uncommenting the lines below: | ||
| # push: | ||
| # branches: [master] | ||
| # paths: ['VMs/Dockerfile'] | ||
| # release: | ||
| # types: [published] | ||
| # | ||
| # Until you do both steps, this workflow does nothing on its own. | ||
| # ------------------------------------------------------------------ | ||
|
|
||
| name: Docker Publish | ||
|
|
||
| on: | ||
| workflow_dispatch: | ||
| # Uncomment the triggers below when ready to automate: | ||
| # push: | ||
| # branches: [master] | ||
| # paths: ['VMs/Dockerfile'] | ||
| # release: | ||
| # types: [published] | ||
|
|
||
| env: | ||
| IMAGE_NAME: owasp/benchmark | ||
| PLATFORMS: linux/amd64,linux/arm64 | ||
|
|
||
| jobs: | ||
| build-and-push: | ||
| runs-on: ubuntu-latest | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| steps: | ||
| - name: Checkout repository | ||
| uses: actions/checkout@v4 | ||
|
|
||
| - name: Set up QEMU (multi-arch emulation) | ||
| uses: docker/setup-qemu-action@v3 | ||
|
|
||
| - name: Set up Docker Buildx | ||
| uses: docker/setup-buildx-action@v3 | ||
|
|
||
| - name: Log in to Docker Hub | ||
| uses: docker/login-action@v3 | ||
| with: | ||
| username: ${{ secrets.DOCKERHUB_USERNAME }} | ||
| password: ${{ secrets.DOCKERHUB_TOKEN }} | ||
|
|
||
| - name: Build and push multi-arch image | ||
| uses: docker/build-push-action@v6 | ||
| with: | ||
| context: VMs | ||
| file: VMs/Dockerfile | ||
| platforms: ${{ env.PLATFORMS }} | ||
| push: true | ||
| tags: ${{ env.IMAGE_NAME }}:latest | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| # Multi-Architecture Docker Image — Build and Publish Guide | ||
|
|
||
| This document accompanies PR #445, which switches the BenchmarkJava Docker image | ||
| to a multi-architecture (`linux/amd64` + `linux/arm64`) build via `docker buildx`. | ||
|
|
||
| ## Summary | ||
|
|
||
| The published `owasp/benchmark:latest` Docker image was built on an ARM64 host, | ||
| making it `linux/arm64` only. On amd64 machines (the vast majority of CI runners | ||
| and developer workstations), Docker falls back to QEMU emulation, causing | ||
| startup times over 60 seconds — long enough to break downstream CI (e.g., ZAP | ||
| scans reported in #223). | ||
|
|
||
| The build tooling now uses `docker buildx build` with | ||
| `--platform linux/amd64,linux/arm64`. Docker Hub receives a single manifest | ||
| list that serves the native image for each architecture automatically. | ||
|
|
||
| ## What changed | ||
|
|
||
| | File | Change | | ||
| |------|--------| | ||
| | `VMs/buildDockerImage.sh` | Rewritten to use `docker buildx build` with `--platform linux/amd64,linux/arm64`, `--file VMs/Dockerfile`, and context `VMs`. Builds and pushes a multi-arch manifest list to Docker Hub in one step. | | ||
| | `VMs/Dockerfile` | Collapsed multiple `RUN` layers into single chained commands; added `rm -rf /var/lib/apt/lists/*`; added `EXPOSE 8443` and `CMD ["./runBenchmark.sh"]` so the container starts the benchmark by default. Base image remains `ubuntu:latest` per maintainer preference. | | ||
| | `VMs/runDockerImage.sh` | Updated image tag from `benchmark` to `owasp/benchmark` to match the new build script's output. | | ||
| | `.github/workflows/docker-publish.yml` | New CI workflow (manual trigger only, inactive by default) for automated multi-arch builds. Activation steps below. | | ||
|
|
||
| ## Manual build | ||
|
|
||
| Prerequisites: Docker with buildx support (Docker Desktop 19.03+ or Docker | ||
| Engine with the buildx plugin), and a Docker Hub login with push access to | ||
| the `owasp/benchmark` namespace: | ||
|
|
||
| ```bash | ||
| docker login -u <your-dockerhub-username> | ||
| ``` | ||
|
|
||
| Then, from the **repository root**: | ||
|
|
||
| ```bash | ||
| ./VMs/buildDockerImage.sh | ||
| ``` | ||
|
|
||
| This builds for both amd64 and arm64 and pushes `owasp/benchmark:latest` to | ||
| Docker Hub. `--push` is required because multi-arch manifest lists cannot be | ||
| loaded into the local Docker daemon; build and push happen together. | ||
|
|
||
| ## Running the published image | ||
|
|
||
| After publishing, run the image with: | ||
|
|
||
| ```bash | ||
| ./VMs/runDockerImage.sh | ||
| ``` | ||
|
|
||
| This pulls `owasp/benchmark:latest` from Docker Hub and starts the benchmark | ||
| inside the container. | ||
|
|
||
| ## Activating the GitHub Actions workflow | ||
|
|
||
| The workflow file is at `.github/workflows/docker-publish.yml`, but it only | ||
| runs when manually dispatched until two activation steps are completed. | ||
|
|
||
| ### Step 1: Add Docker Hub secrets | ||
|
|
||
| Go to **Settings > Secrets and variables > Actions** in the GitHub repository | ||
| and add: | ||
|
|
||
| | Secret name | Value | | ||
| |-------------|-------| | ||
| | `DOCKERHUB_USERNAME` | Docker Hub username | | ||
| | `DOCKERHUB_TOKEN` | Docker Hub access token (create at https://hub.docker.com/settings/security) | | ||
|
|
||
| ### Step 2: Enable automatic triggers (optional) | ||
|
|
||
| Open `.github/workflows/docker-publish.yml` and uncomment the trigger lines: | ||
|
|
||
| ```yaml | ||
| on: | ||
| workflow_dispatch: | ||
| # Uncomment when ready: | ||
| push: | ||
| branches: [master] | ||
| paths: ['VMs/Dockerfile'] | ||
| release: | ||
| types: [published] | ||
| ``` | ||
|
|
||
| This rebuilds and pushes the image whenever the Dockerfile is changed on | ||
| `master` or a new GitHub release is published. | ||
|
|
||
| ### Step 3: Test with manual trigger first | ||
|
|
||
| Before enabling automatic triggers, verify the workflow manually: | ||
|
|
||
| 1. Go to **Actions > Docker Publish** in the repository. | ||
| 2. Click **Run workflow**. | ||
| 3. Confirm both architectures appear with: | ||
|
|
||
| ```bash | ||
| docker manifest inspect owasp/benchmark:latest | ||
| ``` | ||
|
|
||
| The output should list entries for both `amd64` and `arm64`. | ||
|
|
||
| ## What was not changed | ||
|
|
||
| | Item | Reason | | ||
| |------|--------| | ||
| | JDK version (17) | Tracked separately in #227. | | ||
| | `bench:bench` user/password | Test image only, not a production deployment. | | ||
| | `timeout 60 ./runBenchmark.sh; exit 0` warm-up | Intentional — caches runtime dependencies into the image. | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,16 +1,32 @@ | ||
| # Pull in latest version of ubuntu. This builds an image using the OS native to this platform. | ||
| docker pull ubuntu:latest | ||
| # Remove any ubuntu:<none> image if it was left behind by a new version of ubuntu:latest being pulled | ||
| i=$(docker images | grep "ubuntu" | grep "<none" | awk '{print $3}') | ||
| if [ "$i" ] | ||
| then | ||
| docker rmi $i | ||
| #!/usr/bin/env bash | ||
| set -euo pipefail | ||
|
|
||
| IMAGE="owasp/benchmark" | ||
| TAG="latest" | ||
| PLATFORMS="linux/amd64,linux/arm64" | ||
| BUILDER_NAME="benchmark-multiarch" | ||
|
|
||
| # Create (or re-use) a buildx builder that supports multi-platform builds. | ||
| if ! docker buildx inspect "$BUILDER_NAME" >/dev/null 2>&1; then | ||
| echo "Creating buildx builder: $BUILDER_NAME" | ||
| docker buildx create --name "$BUILDER_NAME" --use | ||
| else | ||
| docker buildx use "$BUILDER_NAME" | ||
| fi | ||
|
|
||
| # Since Docker doesn't auto delete anything, just like for the Ubuntu update, delete any existing benchmark:latest image before building a new one | ||
| docker image rm benchmark:latest | ||
| docker build -t benchmark . | ||
| # Build and push a multi-architecture image in one step. | ||
| # --push is required because multi-arch manifest lists cannot be loaded into | ||
| # the local daemon. The image is pushed directly to Docker Hub, so this | ||
| # script requires `docker login` first. | ||
| # Run this script from the repository root; paths below mirror the CI | ||
| # workflow (.github/workflows/docker-publish.yml). | ||
| echo "Building ${IMAGE}:${TAG} for ${PLATFORMS} ..." | ||
| docker buildx build \ | ||
| --platform "$PLATFORMS" \ | ||
| --tag "${IMAGE}:${TAG}" \ | ||
| --file VMs/Dockerfile \ | ||
| --push \ | ||
| VMs | ||
|
|
||
| # Once verified/tested, to publish an update to the OWASP Benchmark Docker image, run the following: | ||
| # docker push owasp/benchmark:latest | ||
| echo "Done. Published ${IMAGE}:${TAG} for ${PLATFORMS}." | ||
|
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,2 +1,2 @@ | ||
| docker run -t -i -p 8443:8443 --rm benchmark /bin/bash -c "git pull && ./runRemoteAccessibleBenchmark.sh" | ||
| docker run -t -i -p 8443:8443 --rm owasp/benchmark /bin/bash -c "git pull && ./runRemoteAccessibleBenchmark.sh" | ||
|
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@davewichers (how) do you publish docker images? https://hub.docker.com/r/owasp/benchmark this one is some months old. This workflow could help automating this, but if you prefer manual publish, we do not need it.