From f916b19a6fe95c96fd29163e10dd583662ecbb36 Mon Sep 17 00:00:00 2001 From: Sundram Date: Wed, 20 May 2026 21:13:27 +0530 Subject: [PATCH] feat(cli): add Docker Compose example for the Bruno CLI Docker image (#8036) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat(cli): add Docker Compose example for the Bruno CLI Docker image * Update packages/bruno-cli/docker/README.md Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * refactor(docker-compose): move docker-compose.yml outside the collection folder Keeps packages/bruno-tests/collection/ as pure Bruno collection content (bruno.json, .bru files, environments). The docker-compose example now sits one level up and mounts ./collection into the container, so the collection stays portable. * docs(cli): omit --rm from docker examples, add note explaining when to use it Command examples in docker/README.md no longer suggest --rm by default so users can docker logs / docker inspect the stopped container after a run. A note panel under Step 3 explains what --rm does and when to opt in (CI hygiene, avoiding stopped-container buildup). The version-check command in Step 2 keeps --rm since it is a one-shot sanity probe. Alpine and Debian sub-READMEs follow the same policy; the explanatory note lives only in the main docker/README.md. * feat(bruno-tests): wire docker-compose to emit JSON, JUnit, HTML reports via mounted reports/ dir * docs(cli): apply PR review feedback — rephrase step 3 intro, use latest image tag, use placeholder collection path * docs(cli): apply EM review — trim bru-only steps, generalize options note, dedupe tag table, consolidate gitignore * docs(cli): minor README polish in docker docs (add --rm to CI example, simplify collection path placeholder) * docs(cli): drop --env staging from generic examples, pin CI snippets to :latest, reposition --rm note * docs: updated Readme.md --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- packages/bruno-cli/docker/README.md | 227 ++++++++++-------- .../bruno-cli/docker/images/alpine/README.md | 4 +- .../bruno-cli/docker/images/debian/README.md | 4 +- packages/bruno-tests/.gitignore | 4 + packages/bruno-tests/docker-compose.yml | 14 ++ packages/bruno-tests/reports/README.md | 22 ++ 6 files changed, 177 insertions(+), 98 deletions(-) create mode 100644 packages/bruno-tests/docker-compose.yml create mode 100644 packages/bruno-tests/reports/README.md diff --git a/packages/bruno-cli/docker/README.md b/packages/bruno-cli/docker/README.md index 3a363ed97..b9194b3d3 100644 --- a/packages/bruno-cli/docker/README.md +++ b/packages/bruno-cli/docker/README.md @@ -1,8 +1,8 @@ # Bruno CLI Docker Images -Official Docker images for [Bruno CLI](https://www.usebruno.com), enabling container-native API collection runs in CI/CD pipelines and local environments without requiring Node.js or npm on the host. +Official Docker images for [Bruno CLI](https://www.usebruno.com), enabling container-native API collection runs in CI/CD pipelines and local environments without requiring Node.js or npm on the host. See the [Bruno CLI docs](https://docs.usebruno.com/bru-cli/overview) for CLI usage. -## Image structure +## Folder structure ```text docker/ @@ -12,7 +12,7 @@ docker/ │ ├── Dockerfile ← Alpine Linux variant (smallest, ~141MB) │ └── README.md └── debian/ - ├── Dockerfile ← Debian slim variant (~200MB+, glibc support) + ├── Dockerfile ← Debian slim variant (~162MB, glibc support) └── README.md ``` @@ -43,15 +43,33 @@ docker pull ghcr.io/usebruno/cli:latest ## Tags -| Tag | Example | Variant | -|-----|---------|---------| -| `latest` | `usebruno/cli:latest` | alpine | -| `` | `usebruno/cli:3.3.0` | alpine | -| `` | `usebruno/cli:3.3` | alpine | -| `` | `usebruno/cli:3` | alpine | -| `-alpine` | `usebruno/cli:3.3.0-alpine` | alpine | -| `-debian` | `usebruno/cli:3.3.0-debian` | debian | -| `debian` | `usebruno/cli:debian` | debian | +Every release publishes the following tags to **both** Docker Hub (`usebruno/cli`) and GHCR (`ghcr.io/usebruno/cli`). + +### Alpine variant (default) + +| Tag pattern | Example | Notes | +|-------------|---------|-------| +| `latest` | `usebruno/cli:latest` | Newest release marked as latest. Only moves when the publish workflow is run with "Tag this version as latest" checked. | +| `latest-alpine` | `usebruno/cli:latest-alpine` | Alias of `latest` — also alpine. | +| `alpine` | `usebruno/cli:alpine` | Newest alpine, moves on every alpine publish. | +| `` | `usebruno/cli:3.3.0` | Exact version, immutable. | +| `-alpine` | `usebruno/cli:3.3.0-alpine` | Exact version, explicitly alpine. | +| `` | `usebruno/cli:3.3` | Floats with patch releases (3.3.x). | +| `-alpine` | `usebruno/cli:3.3-alpine` | Same, explicitly alpine. | +| `` | `usebruno/cli:3` | Floats with any 3.x.x release. | +| `-alpine` | `usebruno/cli:3-alpine` | Same, explicitly alpine. | + +### Debian variant + +| Tag pattern | Example | Notes | +|-------------|---------|-------| +| `latest-debian` | `usebruno/cli:latest-debian` | Newest debian release marked as latest (gated by the same checkbox). | +| `debian` | `usebruno/cli:debian` | Newest debian, moves on every debian publish. | +| `-debian` | `usebruno/cli:3.3.0-debian` | Exact version, debian. | +| `-debian` | `usebruno/cli:3.3-debian` | Floats with debian patch releases. | +| `-debian` | `usebruno/cli:3-debian` | Floats with any 3.x.x debian release. | + +The unsuffixed tags (`:latest`, `:3.3.0`, `:3.3`, `:3`, `:alpine`) always resolve to the alpine variant by convention. --- @@ -86,107 +104,91 @@ docker run --rm usebruno/cli --version ### Step 3 — Run your collection -> Mount your collection directory to `/bruno` and pass `bru` arguments directly after the image name. - +> These examples assume you are running `docker` from your Bruno collection directory. Mount that directory to `/bruno` and pass `bru` arguments directly after the image name. If your collection lives elsewhere on disk, see the path-based examples further down. > **Cross-platform note:** the examples below use `$(pwd)` which works in Bash / Zsh / Git Bash / WSL. > On Windows native shells, substitute `$(pwd)` with: > - PowerShell: `${PWD}` > - CMD: `%cd%` +> **Adding `bru` options:** The examples below show docker-specific flags. For all `bru run` options — recurse (`-r`), environments, variables, reporters, bail, and more — see the [Bruno CLI docs](https://docs.usebruno.com/bru-cli/overview). ```bash -# collection at your current directory -docker run --rm -v $(pwd):/bruno usebruno/cli run --env staging +# run every request in the Bruno collection (current dir) +docker run -v $(pwd):/bruno usebruno/cli run -# collection in a subfolder -docker run --rm -v $(pwd):/bruno usebruno/cli run ./api-tests --env staging +# run a specific subfolder (group of requests) within that collection +docker run -v $(pwd):/bruno usebruno/cli run ./api-tests -# single request file -docker run --rm -v $(pwd):/bruno usebruno/cli run ./api-tests/login.bru --env staging +# run a single .bru request file from that collection +docker run -v $(pwd):/bruno usebruno/cli run ./api-tests/login.bru + +# write a JUnit XML report (lands in the current directory because of the bind mount) +docker run -v $(pwd):/bruno usebruno/cli run --reporter-junit results.xml ``` +For Windows CMD users, swap `$(pwd)` with `%cd%`: + +```cmd +docker run -v %cd%:/bruno usebruno/cli run +``` + +#### Running a collection that lives at a different path + +If your collection is not in your current directory, point `docker` at its path (relative or absolute) instead of `$(pwd)`: + +```bash +# run every request in a collection at an arbitrary path +docker run -v /path/to/your/collection:/bruno usebruno/cli run + +# run a single .bru file from a collection at an arbitrary path +docker run -v /path/to/your/collection:/bruno usebruno/cli run ./auth/login.bru +``` + +> **Note on `--rm`:** Examples below include `--rm`. Docker keeps stopped containers around after they exit, which lets you `docker logs` or `docker inspect` them later for debugging. If you'd rather have Docker auto-delete the container as soon as `bru` finishes — useful for CI runs or to avoid `docker ps -a` filling up with stale entries — append `--rm` to any `docker run` (or `docker compose run`) command: +> +> ```bash +> docker run --rm -v $(pwd):/bruno usebruno/cli run +> ``` +> +> It's purely a cleanup convenience; it doesn't affect the image, mounts, stdout output, or exit code. + --- ### Step 4 — Choose your environment ```bash -docker run --rm -v $(pwd):/bruno usebruno/cli run --env local -docker run --rm -v $(pwd):/bruno usebruno/cli run --env staging -docker run --rm -v $(pwd):/bruno usebruno/cli run --env production +docker run -v $(pwd):/bruno usebruno/cli run --env local +docker run -v $(pwd):/bruno usebruno/cli run --env staging +docker run -v $(pwd):/bruno usebruno/cli run --env production ``` --- -### Step 5 — Pass variables at runtime - -```bash -# override a single variable -docker run --rm \ - -v $(pwd):/bruno \ - usebruno/cli run --env staging --env-var API_KEY=your_key - -# override multiple variables -docker run --rm \ - -v $(pwd):/bruno \ - usebruno/cli run --env staging \ - --env-var BASE_URL=https://api.example.com \ - --env-var API_KEY=secret123 - -# load variables from a file -docker run --rm \ - -v $(pwd):/bruno \ - --env-file .env \ - usebruno/cli run --env staging -``` - ---- - -### Step 6 — Save test results - -```bash -# JSON report -docker run --rm \ - -v $(pwd):/bruno \ - usebruno/cli run --env staging --output results.json --format json - -# JUnit XML report (for CI test reporters) -docker run --rm \ - -v $(pwd):/bruno \ - usebruno/cli run --env staging --output results.xml --format junit -``` - ---- - -### Step 7 — Stop on first failure - -```bash -docker run --rm -v $(pwd):/bruno usebruno/cli run --env staging --bail -``` - ---- - -### Step 8 — Pin the right version +### Step 5 — Pin the right version ```bash # exact version — safest for production, no surprise updates -docker run --rm -v $(pwd):/bruno usebruno/cli:3.3.0 run --env staging +docker run -v $(pwd):/bruno usebruno/cli:3.3.0 run # major.minor — gets patch fixes automatically -docker run --rm -v $(pwd):/bruno usebruno/cli:3.3 run --env staging +docker run -v $(pwd):/bruno usebruno/cli:3.3 run # latest — always newest, not recommended for production CI -docker run --rm -v $(pwd):/bruno usebruno/cli:latest run --env staging +docker run -v $(pwd):/bruno usebruno/cli:latest run ``` --- -### Step 9 — Choose alpine or debian +### Step 6 — Choose alpine or debian ```bash # alpine (default) — use this for most cases -docker run --rm -v $(pwd):/bruno usebruno/cli:3.3.0 run --env staging +docker run -v $(pwd):/bruno usebruno/cli:3.3.0 run + +# alpine — explicitly use the alpine-based image variant +docker run -v $(pwd):/bruno usebruno/cli:3.3.0-alpine run # debian — use if you hit SSL, glibc, or native module issues -docker run --rm -v $(pwd):/bruno usebruno/cli:3.3.0-debian run --env staging +docker run -v $(pwd):/bruno usebruno/cli:3.3.0-debian run ``` --- @@ -224,14 +226,14 @@ jobs: run: | docker run --rm \ -v ${{ github.workspace }}:/bruno \ - usebruno/cli:3.3 run --env staging --output results.xml --format junit + usebruno/cli:latest run --output results.xml --format junit - name: Publish Test Report uses: dorny/test-reporter@v3 - if: always() + if: success() || failure() with: name: Bruno Test Results - path: results.xml + path: ${{github.workspace}}/results.xml reporter: java-junit ``` @@ -239,9 +241,9 @@ jobs: ```yaml api-tests: - image: usebruno/cli:3.3 + image: usebruno/cli:latest script: - - bru run --env staging --output results.xml --format junit + - bru run --output results.xml --format junit artifacts: reports: junit: results.xml @@ -249,6 +251,54 @@ api-tests: --- +## Docker Compose + +### Quick example + +A minimal `docker-compose.yml` for running a Bruno collection alongside your project: + +```yaml +services: + bruno-cli: + image: usebruno/cli:latest + container_name: bruno-cli-runner + volumes: + - /path/to/collection:/bruno + - /path/to/reports:/reports + command: + run . + -r + --env ci + --reporter-json /reports/results.json + --reporter-junit /reports/results.xml + --reporter-html /reports/results.html +``` + +Then run: + +```bash +docker compose run bruno-cli +``` + +The `/path/to/reports:/reports` mount catches the JSON, JUnit XML, and HTML reports on the host — drop any `--reporter-*` flag to skip that format. + +### Try it from this repo + +A ready-to-run `docker-compose.yml` lives in this repo at [`packages/bruno-tests/docker-compose.yml`](../../bruno-tests/docker-compose.yml). It mounts the sibling `collection/` directory into the container, runs the `echo` folder against the `Prod` environment, and writes JSON, JUnit XML, and HTML reports into `packages/bruno-tests/reports/`: + +```bash +cd packages/bruno-tests +docker compose run bruno-cli +``` + +This fires a small set of requests against public endpoints that demonstrate the CLI executing requests and assertions inside a container. + +### Standalone demo + +For a clone-and-run demo with a curated collection, see [`bruno-collections/bruno-cli-docker`](https://github.com/bruno-collections/bruno-cli-docker). + +--- + ## Image details All variants include: @@ -258,14 +308,3 @@ All variants include: - **User:** `node` (UID 1000, non-root) - **Architectures:** `linux/amd64`, `linux/arm64` ---- - -## All version × variant combinations - -| | Alpine | Debian | -|---|---|---| -| `latest` | `usebruno/cli:latest` | `usebruno/cli:debian` | -| `3` | `usebruno/cli:3` | `usebruno/cli:3-debian` | -| `3.3` | `usebruno/cli:3.3` | `usebruno/cli:3.3-debian` | -| `3.3.0` | `usebruno/cli:3.3.0` | `usebruno/cli:3.3.0-debian` | -| `3.2.0` | `usebruno/cli:3.2.0` | `usebruno/cli:3.2.0-debian` | diff --git a/packages/bruno-cli/docker/images/alpine/README.md b/packages/bruno-cli/docker/images/alpine/README.md index e4a08a09b..05c43bf35 100644 --- a/packages/bruno-cli/docker/images/alpine/README.md +++ b/packages/bruno-cli/docker/images/alpine/README.md @@ -20,8 +20,8 @@ docker build \ ```bash # Run a collection -docker run --rm -v $(pwd):/bruno usebruno/cli:alpine run --env staging +docker run -v $(pwd):/bruno usebruno/cli:alpine run # with pinned version -docker run --rm -v $(pwd):/bruno usebruno/cli:3.3.0-alpine run --env staging +docker run -v $(pwd):/bruno usebruno/cli:3.3.0-alpine run ``` diff --git a/packages/bruno-cli/docker/images/debian/README.md b/packages/bruno-cli/docker/images/debian/README.md index abf967d0e..1bce07313 100644 --- a/packages/bruno-cli/docker/images/debian/README.md +++ b/packages/bruno-cli/docker/images/debian/README.md @@ -20,8 +20,8 @@ docker build \ ```bash # Run a collection -docker run --rm -v $(pwd):/bruno usebruno/cli:debian run --env staging +docker run -v $(pwd):/bruno usebruno/cli:debian run # with pinned version -docker run --rm -v $(pwd):/bruno usebruno/cli:3.3.0-debian run --env staging +docker run -v $(pwd):/bruno usebruno/cli:3.3.0-debian run ``` diff --git a/packages/bruno-tests/.gitignore b/packages/bruno-tests/.gitignore index 253e9824f..d547902ca 100644 --- a/packages/bruno-tests/.gitignore +++ b/packages/bruno-tests/.gitignore @@ -105,3 +105,7 @@ dist # TernJS port file .tern-port + +# Bruno CLI docker-compose run reports +reports/* +!reports/README.md diff --git a/packages/bruno-tests/docker-compose.yml b/packages/bruno-tests/docker-compose.yml new file mode 100644 index 000000000..261b4f47b --- /dev/null +++ b/packages/bruno-tests/docker-compose.yml @@ -0,0 +1,14 @@ +services: + bruno-cli: + image: usebruno/cli:latest + container_name: bruno-cli-runner + volumes: + - ./collection:/bruno + - ./reports:/reports + command: + run echo + -r + --env Prod + --reporter-json /reports/results.json + --reporter-junit /reports/results.xml + --reporter-html /reports/results.html diff --git a/packages/bruno-tests/reports/README.md b/packages/bruno-tests/reports/README.md new file mode 100644 index 000000000..6e1e79493 --- /dev/null +++ b/packages/bruno-tests/reports/README.md @@ -0,0 +1,22 @@ +# Bruno CLI — Docker run reports + +This folder is the bind-mount target for the Docker Compose example at [`../docker-compose.yml`](../docker-compose.yml). + +When you run: + +```bash +cd packages/bruno-tests +docker compose run bruno-cli +``` + +the container writes three report files into this directory: + +| File | Format | Purpose | +|------|--------|---------| +| `results.json` | JSON | Machine-readable run summary (request/response, timings, assertion results) | +| `results.xml` | JUnit XML | For CI test reporters (GitHub Actions, GitLab CI, Jenkins, etc.) | +| `results.html` | HTML | Human-readable report you can open in a browser | + +The files themselves are gitignored — only this `README.md` and the `.gitignore` are tracked, which keeps the folder present in the repo so the `./reports:/reports` bind mount has somewhere to land without needing manual `mkdir` first. + +To skip a format, drop the corresponding `--reporter-*` flag from the `command:` block in `docker-compose.yml`.