|
| 1 | +# Multi-Architecture Docker Image — Build and Publish Guide |
| 2 | + |
| 3 | +This document accompanies PR #445, which switches the BenchmarkJava Docker image |
| 4 | +to a multi-architecture (`linux/amd64` + `linux/arm64`) build via `docker buildx`. |
| 5 | + |
| 6 | +## Summary |
| 7 | + |
| 8 | +The published `owasp/benchmark:latest` Docker image was built on an ARM64 host, |
| 9 | +making it `linux/arm64` only. On amd64 machines (the vast majority of CI runners |
| 10 | +and developer workstations), Docker falls back to QEMU emulation, causing |
| 11 | +startup times over 60 seconds — long enough to break downstream CI (e.g., ZAP |
| 12 | +scans reported in #223). |
| 13 | + |
| 14 | +The build tooling now uses `docker buildx build` with |
| 15 | +`--platform linux/amd64,linux/arm64`. Docker Hub receives a single manifest |
| 16 | +list that serves the native image for each architecture automatically. |
| 17 | + |
| 18 | +## What changed |
| 19 | + |
| 20 | +| File | Change | |
| 21 | +|------|--------| |
| 22 | +| `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. | |
| 23 | +| `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. | |
| 24 | +| `VMs/runDockerImage.sh` | Updated image tag from `benchmark` to `owasp/benchmark` to match the new build script's output. | |
| 25 | +| `.github/workflows/docker-publish.yml` | New CI workflow (manual trigger only, inactive by default) for automated multi-arch builds. Activation steps below. | |
| 26 | + |
| 27 | +## Manual build |
| 28 | + |
| 29 | +Prerequisites: Docker with buildx support (Docker Desktop 19.03+ or Docker |
| 30 | +Engine with the buildx plugin), and a Docker Hub login with push access to |
| 31 | +the `owasp/benchmark` namespace: |
| 32 | + |
| 33 | +```bash |
| 34 | +docker login -u <your-dockerhub-username> |
| 35 | +``` |
| 36 | + |
| 37 | +Then, from the **repository root**: |
| 38 | + |
| 39 | +```bash |
| 40 | +./VMs/buildDockerImage.sh |
| 41 | +``` |
| 42 | + |
| 43 | +This builds for both amd64 and arm64 and pushes `owasp/benchmark:latest` to |
| 44 | +Docker Hub. `--push` is required because multi-arch manifest lists cannot be |
| 45 | +loaded into the local Docker daemon; build and push happen together. |
| 46 | + |
| 47 | +## Running the published image |
| 48 | + |
| 49 | +After publishing, run the image with: |
| 50 | + |
| 51 | +```bash |
| 52 | +./VMs/runDockerImage.sh |
| 53 | +``` |
| 54 | + |
| 55 | +This pulls `owasp/benchmark:latest` from Docker Hub and starts the benchmark |
| 56 | +inside the container. |
| 57 | + |
| 58 | +## Activating the GitHub Actions workflow |
| 59 | + |
| 60 | +The workflow file is at `.github/workflows/docker-publish.yml`, but it only |
| 61 | +runs when manually dispatched until two activation steps are completed. |
| 62 | + |
| 63 | +### Step 1: Add Docker Hub secrets |
| 64 | + |
| 65 | +Go to **Settings > Secrets and variables > Actions** in the GitHub repository |
| 66 | +and add: |
| 67 | + |
| 68 | +| Secret name | Value | |
| 69 | +|-------------|-------| |
| 70 | +| `DOCKERHUB_USERNAME` | Docker Hub username | |
| 71 | +| `DOCKERHUB_TOKEN` | Docker Hub access token (create at https://hub.docker.com/settings/security) | |
| 72 | + |
| 73 | +### Step 2: Enable automatic triggers (optional) |
| 74 | + |
| 75 | +Open `.github/workflows/docker-publish.yml` and uncomment the trigger lines: |
| 76 | + |
| 77 | +```yaml |
| 78 | +on: |
| 79 | + workflow_dispatch: |
| 80 | + # Uncomment when ready: |
| 81 | + push: |
| 82 | + branches: [master] |
| 83 | + paths: ['VMs/Dockerfile'] |
| 84 | + release: |
| 85 | + types: [published] |
| 86 | +``` |
| 87 | +
|
| 88 | +This rebuilds and pushes the image whenever the Dockerfile is changed on |
| 89 | +`master` or a new GitHub release is published. |
| 90 | + |
| 91 | +### Step 3: Test with manual trigger first |
| 92 | + |
| 93 | +Before enabling automatic triggers, verify the workflow manually: |
| 94 | + |
| 95 | +1. Go to **Actions > Docker Publish** in the repository. |
| 96 | +2. Click **Run workflow**. |
| 97 | +3. Confirm both architectures appear with: |
| 98 | + |
| 99 | + ```bash |
| 100 | + docker manifest inspect owasp/benchmark:latest |
| 101 | + ``` |
| 102 | + |
| 103 | + The output should list entries for both `amd64` and `arm64`. |
| 104 | + |
| 105 | +## What was not changed |
| 106 | + |
| 107 | +| Item | Reason | |
| 108 | +|------|--------| |
| 109 | +| JDK version (17) | Tracked separately in #227. | |
| 110 | +| `bench:bench` user/password | Test image only, not a production deployment. | |
| 111 | +| `timeout 60 ./runBenchmark.sh; exit 0` warm-up | Intentional — caches runtime dependencies into the image. | |
0 commit comments