[PR #3420] docs(docker): add a container image and guide #5733

Open
opened 2026-10-31 01:09:01 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/3420
Author: @Rinkia
Created: 10/14/2026
Status: 🔄 Open

Base: main ← Head: docs/docker-image


📝 Commits (10+)

  • ec75ca0 docs(docker): add a container image and guide
  • fcb946a test(release): cover the Dockerfile version pin
  • 9134502 fix(docker): pin the build platform and derive the browser from REA
  • 5699414 Merge remote-tracking branch 'upstream/main' into docs/docker-image
  • 473369b Merge remote-tracking branch 'upstream/main' into docs/docker-image
  • 330ab36 Merge remote-tracking branch 'upstream/main' into docs/docker-image
  • 999b679 docs(docker): pin rea-agents 6.5.0 and document the JADX heap
  • f47521e docs(docker): document the JADX doctor check
  • 46c2f04 docs(docker): narrow the image to rea-agents with caller-supplied tools
  • 7346794 Merge remote-tracking branch 'upstream/main' into docs/docker-image

📊 Changes

5 files changed (+203 additions, -0 deletions)

View changed files

➕ docker/Dockerfile (+19 -0)
📝 docs/.vitepress/config.ts (+1 -0)
➕ docs/docker.md (+168 -0)
📝 release-please-config.json (+1 -0)
📝 tests/conformance/releaseConfiguration.test.ts (+14 -0)

📄 Description

Summary

Adds a Dockerfile and a container guide so REA's MCP server and CLI can run in a Linux container. Narrowed after review to existing boundaries: the image contains only rea-agents on the official Node.js image. Ghidra, a JDK, the JADX engine and browsers are supplied by the caller through mounts and the existing environment variables, and no browser sandbox setting is changed image-wide. Refs #3372.

Problem and expected behavior

REA has no container setup today. Running it in Docker means rediscovering several details: docker run -i for stdio MCP, container paths, read-only target mounts, memory limits for Ghidra and JADX, how to point REA at caller-supplied tools, and how CDP attach can work when each session gets a fresh container.

After this change, docker build -t rea docker/ produces a small image (node:24-bookworm-slim + rea-agents). With a caller-supplied Ghidra 12.1.x, JDK 21 and JADX JAR mounted read-only, rea doctor --provider ghidra|jadx is healthy and Ghidra and JADX operations work. CDP observation works against a caller-chosen headless browser container that shares the network namespace. docs/docker.md explains all of this.

Change and scope

  • docker/Dockerfile: node:24-bookworm-slim base, procps (REA's Linux process supervision needs ps), rea-agents from npm, an unprivileged rea user, and rea mcp as the default command. It doesn't download Ghidra, a JDK, the JADX JAR or a browser, and sets no REA_BROWSER_NO_SANDBOX.
  • docs/docker.md: build; supplying the tools (GHIDRA_INSTALL_DIR, JAVA_HOME, REA_JADX_MCP_JAR, with a Docker-volume example because a Windows bind mount can't reproduce a JDK's symlinks); MCP registration; targets and paths; memory (Ghidra and JADX heaps); browsers; limits; updating.
    • Browsers, CDP: a caller-chosen headless-browser container with --network container:<name>, so its debugging port is loopback for REA.
    • Browsers, launch-based scenarios: these need a caller-built derived image, with -e REA_BROWSER_NO_SANDBOX=true as a documented per-run opt-in.
  • docs/.vitepress/config.ts: a sidebar entry.
  • release-please-config.json: registers docker/Dockerfile as a generic extra file. The rea-agents@6.7.0 pin sits between x-release-please-start-version and x-release-please-end markers, the same mechanism docs/installation.md uses.

This keeps within AGENTS.md: Ghidra and IDA stay bring-your-own, and nothing installs Java, Ghidra or a browser. Node.js comes from the official base image as REA's runtime; it isn't installed onto a user's system.

Not included: a published image, CI that builds the image, bundled Ghidra/JDK/JADX/browser, Hopper/IDA/JEB, firmware/packet/signal tools (and prlimit), and ARM64. The README is unchanged.

Follow the contribution scope. This adds no provider or capability; it packages REA itself and documents use of caller-supplied tools. The bundled-toolchain and image-wide sandbox questions raised in review are removed from the recipe rather than assumed; #3372 can still decide whether a fuller image is wanted later.

Contract and boundary impact

  • Semantic owner and earliest changed stage: documentation and packaging (new docker/ directory); no source change.
  • Contribution scope fit and linked maintainer decision: narrowed to existing boundaries (caller-supplied tools, no image-wide sandbox change); #3372 remains open for any future fuller image.
  • CLI and MCP/tool-catalog contract: none.
  • Provider, bridge, target-format, or platform compatibility: none in REA. The image is Linux x64 only.
  • Evidence, artifact, provenance, or reconstruction contract: none.
  • Target selection, authority, upstream behavior, and cleanup details (if applicable): the guide documents REA_BROWSER_NO_SANDBOX=true only as an explicit per-run opt-in for a caller-built derived image.
  • Generated metadata (docs/public/product-catalog.json), package, or installation impact: no generated files committed. release-please-config.json gains one extra file.

Expected effects (check known effects; use documentation-only on its own).

The image build downloads the node base image and rea-agents. The documented workflow reads mounted targets and caller-supplied tools, and launches the caller's Ghidra/JADX inside the container. The CDP example attaches to a caller-run browser container that can load network pages. The repository's own source behaviour is unchanged.
Unchecked items do not establish absence; leave uncertainties visible.

  • Read existing files or captured data.
  • Launch or attach to a process.
  • Inject instrumentation or run scripts/code.
  • Change process memory, registers, files, or configuration.
  • Contact network services.
  • Recover protected code or work around protections.
  • Documentation or usability only; no target interaction.
  • Not sure yet; investigation or maintainer guidance needed.

Evidence and regression coverage

  • Tests added or updated: tests/conformance/releaseConfiguration.test.ts expects docker/Dockerfile in release-please extra-files and asserts that its marked block installs rea-agents@<package version>.
  • Base reproduction or other evidence: executed. The commands below ran against an image built from this branch's narrowed docker/Dockerfile.
  • User-visible CLI/MCP output (if applicable): not applicable.
  • Remaining proof gaps:
    • No CI builds the image.
    • Not tried on Linux or macOS hosts, ARM64, or rootless Docker/Podman.
    • Launch-based browser scenarios in a derived image were not re-run for this narrowed version; the earlier bundled image verified Chromium with --no-sandbox.
    • The caller-supplied tools in my run came from a Docker volume populated from a previous build, not from fresh upstream downloads.

Validation performed

Host: Windows 11, Docker Desktop (WSL2, linux/amd64). Container: --memory 3g -e GHIDRA_HEADLESS_MAXMEM=2G. Targets mounted read-only at /targets. Tools supplied from a read-only Docker volume (Ghidra 12.1.4, Temurin JDK 21.0.12, jadx-headless-mcp-0.7.1-all.jar) via GHIDRA_INSTALL_DIR, JAVA_HOME and REA_JADX_MCP_JAR.

  • docker build --platform linux/amd64 -t rea-slim docker/: succeeded. Rebuilt on 2026-10-18 after merging main and moving the pin to 6.7.0: the image is 900 MB (the previous bundled image was 4.47 GB). rea --version is 6.7.0; ps is present; no java or chromium; runs as rea.
  • On that 6.7.0 image, rea doctor --provider ghidra and rea doctor --provider jadx with the mounted tools again report healthy: true, and tests/conformance/releaseConfiguration.test.ts passes 6/6 on the merged tree. The other checks below were run on the 6.5.0 build.
  • rea doctor --provider ghidra and rea doctor --provider jadx with the mounted tools: both healthy: true. The remaining failed rows are Hopper, IDA and the skill identity, which aren't expected in a container.
  • rea inspect <ELF> --provider ghidra on a small Rust ELF: 685 procedures and 1,349 strings in 87 s.
  • rea inspect-android-package /targets/binaryeye.apk (8.7 MB): complete result from provider jadx in 7 s.
  • CDP: chromedp/headless-shell:156.0.8078.12 run as rea-browser, then rea list-browser-targets http://127.0.0.1:9222 from the narrowed image with --network container:rea-browser. This returned Evidence from rea-cdp-browser with browser Chrome/156.0.8078.12.
  • npm run test:local -- tests/conformance/releaseConfiguration.test.ts tests/conformance/readmeConsistency.test.ts: 11/11 passed (node:24-bookworm, clean npm ci).
  • npx oxfmt --check docs/docker.md: passes after formatting the tools table.
  • npm run docs:check: exit 0.

Compatibility, safety, and release

  • Breaking changes or migration steps: none (the image was never released).
  • Real Hopper/Ghidra, browser, or OS coverage: real caller-supplied Ghidra 12.1.4 and JADX 0.7.1 inside the container, and CDP against Chrome 156 in a sidecar container, on a Windows 11 / Docker Desktop host. Hopper and IDA are not covered.
  • Package or release metadata impact: docker/ is not in the npm package. Release-please will bump the Dockerfile's rea-agents pin.
  • Security, privacy, process, or containment review:
    • The image sets no browser sandbox flag and contains no browser.
    • The sidecar browser's isolation is the caller's chosen image configuration, and the guide says so.
    • REA_BROWSER_NO_SANDBOX=true appears only as a documented per-run opt-in for derived images.
    • The image runs as a non-root user, and the guide recommends read-only target and tool mounts.

Author readiness

Human owner: @Rinkia

  • I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work.
  • I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps.
  • I declare this PR ready for initial maintainer review.

Before merge

  • This PR addresses a concrete problem or an agreed enhancement.
  • Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff.
  • The PR has one focused outcome and the title follows type(scope): outcome.
  • Related issue is linked, or the reason for not linking one is stated above.
  • Tests cover changed observable behavior and meaningful failure paths.
  • Owning docs, contracts, and generated metadata are updated where needed.
  • User-visible CLI/MCP changes include representative output.
  • I checked the final diff for secrets, unrelated cleanup, and unsupported claims.

🤖 Generated with Claude Code


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/3420 **Author:** [@Rinkia](https://github.com/Rinkia) **Created:** 10/14/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `docs/docker-image` --- ### 📝 Commits (10+) - [`ec75ca0`](https://github.com/morluto/rea/commit/ec75ca09ef93612b7982d6990c5ec46909a42e06) docs(docker): add a container image and guide - [`fcb946a`](https://github.com/morluto/rea/commit/fcb946a477b60287fdd37696cb39bb961cfcbca5) test(release): cover the Dockerfile version pin - [`9134502`](https://github.com/morluto/rea/commit/913450283b63b39116820cf3f360bd906d09e38c) fix(docker): pin the build platform and derive the browser from REA - [`5699414`](https://github.com/morluto/rea/commit/5699414f927d7b2ca57ea30e1e6b4e610fbbb689) Merge remote-tracking branch 'upstream/main' into docs/docker-image - [`473369b`](https://github.com/morluto/rea/commit/473369b88934b68d0cf2599300ef2099a7c56cfa) Merge remote-tracking branch 'upstream/main' into docs/docker-image - [`330ab36`](https://github.com/morluto/rea/commit/330ab36d0d6bfb4d433f2b3f0dbd254701cf92a7) Merge remote-tracking branch 'upstream/main' into docs/docker-image - [`999b679`](https://github.com/morluto/rea/commit/999b6792031e3f146472f92e6658c4b671d7e642) docs(docker): pin rea-agents 6.5.0 and document the JADX heap - [`f47521e`](https://github.com/morluto/rea/commit/f47521e030bff1851948c5049b34712a4c0d6ec3) docs(docker): document the JADX doctor check - [`46c2f04`](https://github.com/morluto/rea/commit/46c2f047071bfb1cb2b487856c01e38ae4dbd3ca) docs(docker): narrow the image to rea-agents with caller-supplied tools - [`7346794`](https://github.com/morluto/rea/commit/73467948fcdbbbbb785107cc022cfb2d0754bb2d) Merge remote-tracking branch 'upstream/main' into docs/docker-image ### 📊 Changes **5 files changed** (+203 additions, -0 deletions) <details> <summary>View changed files</summary> ➕ `docker/Dockerfile` (+19 -0) 📝 `docs/.vitepress/config.ts` (+1 -0) ➕ `docs/docker.md` (+168 -0) 📝 `release-please-config.json` (+1 -0) 📝 `tests/conformance/releaseConfiguration.test.ts` (+14 -0) </details> ### 📄 Description ## Summary Adds a Dockerfile and a container guide so REA's MCP server and CLI can run in a Linux container. Narrowed after review to existing boundaries: the image contains only `rea-agents` on the official Node.js image. Ghidra, a JDK, the JADX engine and browsers are supplied by the caller through mounts and the existing environment variables, and no browser sandbox setting is changed image-wide. Refs #3372. ## Problem and expected behavior REA has no container setup today. Running it in Docker means rediscovering several details: `docker run -i` for stdio MCP, container paths, read-only target mounts, memory limits for Ghidra and JADX, how to point REA at caller-supplied tools, and how CDP attach can work when each session gets a fresh container. After this change, `docker build -t rea docker/` produces a small image (`node:24-bookworm-slim` + `rea-agents`). With a caller-supplied Ghidra 12.1.x, JDK 21 and JADX JAR mounted read-only, `rea doctor --provider ghidra|jadx` is healthy and Ghidra and JADX operations work. CDP observation works against a caller-chosen headless browser container that shares the network namespace. `docs/docker.md` explains all of this. ## Change and scope - `docker/Dockerfile`: `node:24-bookworm-slim` base, `procps` (REA's Linux process supervision needs `ps`), `rea-agents` from npm, an unprivileged `rea` user, and `rea mcp` as the default command. It doesn't download Ghidra, a JDK, the JADX JAR or a browser, and sets no `REA_BROWSER_NO_SANDBOX`. - `docs/docker.md`: build; supplying the tools (`GHIDRA_INSTALL_DIR`, `JAVA_HOME`, `REA_JADX_MCP_JAR`, with a Docker-volume example because a Windows bind mount can't reproduce a JDK's symlinks); MCP registration; targets and paths; memory (Ghidra and JADX heaps); browsers; limits; updating. - Browsers, CDP: a caller-chosen headless-browser container with `--network container:<name>`, so its debugging port is loopback for REA. - Browsers, launch-based scenarios: these need a caller-built derived image, with `-e REA_BROWSER_NO_SANDBOX=true` as a documented per-run opt-in. - `docs/.vitepress/config.ts`: a sidebar entry. - `release-please-config.json`: registers `docker/Dockerfile` as a generic extra file. The `rea-agents@6.7.0` pin sits between `x-release-please-start-version` and `x-release-please-end` markers, the same mechanism `docs/installation.md` uses. This keeps within AGENTS.md: Ghidra and IDA stay bring-your-own, and nothing installs Java, Ghidra or a browser. Node.js comes from the official base image as REA's runtime; it isn't installed onto a user's system. Not included: a published image, CI that builds the image, bundled Ghidra/JDK/JADX/browser, Hopper/IDA/JEB, firmware/packet/signal tools (and `prlimit`), and ARM64. The README is unchanged. Follow the [contribution scope](https://github.com/morluto/rea/blob/main/CONTRIBUTING.md#contribution-scope). This adds no provider or capability; it packages REA itself and documents use of caller-supplied tools. The bundled-toolchain and image-wide sandbox questions raised in review are removed from the recipe rather than assumed; #3372 can still decide whether a fuller image is wanted later. ## Contract and boundary impact - Semantic owner and earliest changed stage: documentation and packaging (new `docker/` directory); no source change. - Contribution scope fit and linked maintainer decision: narrowed to existing boundaries (caller-supplied tools, no image-wide sandbox change); #3372 remains open for any future fuller image. - CLI and MCP/tool-catalog contract: none. - Provider, bridge, target-format, or platform compatibility: none in REA. The image is Linux x64 only. - Evidence, artifact, provenance, or reconstruction contract: none. - Target selection, authority, upstream behavior, and cleanup details (if applicable): the guide documents `REA_BROWSER_NO_SANDBOX=true` only as an explicit per-run opt-in for a caller-built derived image. - Generated metadata (`docs/public/product-catalog.json`), package, or installation impact: no generated files committed. `release-please-config.json` gains one extra file. Expected effects (check known effects; use documentation-only on its own). _The image build downloads the `node` base image and `rea-agents`. The documented workflow reads mounted targets and caller-supplied tools, and launches the caller's Ghidra/JADX inside the container. The CDP example attaches to a caller-run browser container that can load network pages. The repository's own source behaviour is unchanged._ Unchecked items do not establish absence; leave uncertainties visible. - [x] Read existing files or captured data. - [x] Launch or attach to a process. - [ ] Inject instrumentation or run scripts/code. - [ ] Change process memory, registers, files, or configuration. - [x] Contact network services. - [ ] Recover protected code or work around protections. - [ ] Documentation or usability only; no target interaction. - [ ] Not sure yet; investigation or maintainer guidance needed. ## Evidence and regression coverage - Tests added or updated: `tests/conformance/releaseConfiguration.test.ts` expects `docker/Dockerfile` in release-please `extra-files` and asserts that its marked block installs `rea-agents@<package version>`. - Base reproduction or other evidence: executed. The commands below ran against an image built from this branch's narrowed `docker/Dockerfile`. - User-visible CLI/MCP output (if applicable): not applicable. - Remaining proof gaps: - No CI builds the image. - Not tried on Linux or macOS hosts, ARM64, or rootless Docker/Podman. - Launch-based browser scenarios in a derived image were not re-run for this narrowed version; the earlier bundled image verified Chromium with `--no-sandbox`. - The caller-supplied tools in my run came from a Docker volume populated from a previous build, not from fresh upstream downloads. ## Validation performed Host: Windows 11, Docker Desktop (WSL2, linux/amd64). Container: `--memory 3g -e GHIDRA_HEADLESS_MAXMEM=2G`. Targets mounted read-only at `/targets`. Tools supplied from a read-only Docker volume (Ghidra 12.1.4, Temurin JDK 21.0.12, `jadx-headless-mcp-0.7.1-all.jar`) via `GHIDRA_INSTALL_DIR`, `JAVA_HOME` and `REA_JADX_MCP_JAR`. - `docker build --platform linux/amd64 -t rea-slim docker/`: succeeded. Rebuilt on 2026-10-18 after merging `main` and moving the pin to 6.7.0: the image is 900 MB (the previous bundled image was 4.47 GB). `rea --version` is 6.7.0; `ps` is present; no `java` or `chromium`; runs as `rea`. - On that 6.7.0 image, `rea doctor --provider ghidra` and `rea doctor --provider jadx` with the mounted tools again report `healthy: true`, and `tests/conformance/releaseConfiguration.test.ts` passes 6/6 on the merged tree. The other checks below were run on the 6.5.0 build. - `rea doctor --provider ghidra` and `rea doctor --provider jadx` with the mounted tools: both `healthy: true`. The remaining failed rows are Hopper, IDA and the skill identity, which aren't expected in a container. - `rea inspect <ELF> --provider ghidra` on a small Rust ELF: 685 procedures and 1,349 strings in 87 s. - `rea inspect-android-package /targets/binaryeye.apk` (8.7 MB): complete result from provider `jadx` in 7 s. - CDP: `chromedp/headless-shell:156.0.8078.12` run as `rea-browser`, then `rea list-browser-targets http://127.0.0.1:9222` from the narrowed image with `--network container:rea-browser`. This returned Evidence from `rea-cdp-browser` with browser `Chrome/156.0.8078.12`. - `npm run test:local -- tests/conformance/releaseConfiguration.test.ts tests/conformance/readmeConsistency.test.ts`: 11/11 passed (node:24-bookworm, clean `npm ci`). - `npx oxfmt --check docs/docker.md`: passes after formatting the tools table. - `npm run docs:check`: exit 0. ## Compatibility, safety, and release - Breaking changes or migration steps: none (the image was never released). - Real Hopper/Ghidra, browser, or OS coverage: real caller-supplied Ghidra 12.1.4 and JADX 0.7.1 inside the container, and CDP against Chrome 156 in a sidecar container, on a Windows 11 / Docker Desktop host. Hopper and IDA are not covered. - Package or release metadata impact: `docker/` is not in the npm package. Release-please will bump the Dockerfile's `rea-agents` pin. - Security, privacy, process, or containment review: - The image sets no browser sandbox flag and contains no browser. - The sidecar browser's isolation is the caller's chosen image configuration, and the guide says so. - `REA_BROWSER_NO_SANDBOX=true` appears only as a documented per-run opt-in for derived images. - The image runs as a non-root user, and the guide recommends read-only target and tool mounts. ## Author readiness Human owner: @Rinkia - [x] I reviewed the final diff and relevant existing code, understand the change and its edge cases, and take responsibility for the complete PR, including AI-assisted work. - [x] I checked the evidence above, confirmed it supports the current change, and recorded meaningful validation gaps. - [x] I declare this PR ready for initial maintainer review. ## Before merge - [x] This PR addresses a concrete problem or an agreed enhancement. - [ ] Material scope and authority questions are resolved, and any required maintainer scope decision covers the final diff. - [x] The PR has one focused outcome and the title follows `type(scope): outcome`. - [x] Related issue is linked, or the reason for not linking one is stated above. - [ ] Tests cover changed observable behavior and meaningful failure paths. - [x] Owning docs, contracts, and generated metadata are updated where needed. - [ ] User-visible CLI/MCP changes include representative output. - [ ] I checked the final diff for secrets, unrelated cleanup, and unsupported claims. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#5733
No description provided.