Files
synapbus/image-build
Algis DumbrisandClaude Opus 4.6 ddbb1bd329 fix(docker): tmpfs /tmp mounted rw,exec,size=128m
Docker Desktop's default noexec on tmpfs broke the "download a CLI
to /tmp, chmod +x, run it" workflow — exactly what the doc-gardener
inspector needs to verify docs.mcpproxy.app against the real
mcpproxy binary. Previously the agent spent ~10 minutes in a self-
debug loop discovering the noexec, falling back to /home/agent,
running into externally-managed Python, missing python3-venv, etc.

With /tmp exec, the inspector's own install pipeline works on the
first try: curl | tar | chmod | run. First real run produced a
72-claim drift report (21 matched / 1 drifted / 50 missing) against
mcpproxy v0.24.4 in ~8 minutes, no REVISE loop.

The 64m → 128m bump gives breathing room for curl'd tarballs that
need a temp extraction directory alongside the final binary.

Inspector prompt updated to tell the agent about the /tmp install
path explicitly and forbid the previous /home/agent detours. Also
updated the coordinator brief template to match.

Note the image itself is UNCHANGED — we deliberately do NOT bake
mcpproxy (or any other domain-specific tool) into synapbus-agent.
The image stays a blank Linux shell with Node + Python + core tools,
and each example's prompt teaches its agent how to install whatever
it needs. This keeps the gardener universal: swap in any other docs
domain and the inspector figures out what to install on demand.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 13:07:58 +03:00
..

SynapBus container images

The docker harness backend (internal/harness/docker/) runs each agent inside an ephemeral container. This directory holds the canonical agent image SynapBus's bundled examples reference.

synapbus-agent

The default image. Debian bookworm-slim base with:

  • gemini CLI (@google/gemini-cli)
  • claude CLI (@anthropic-ai/claude-code)
  • tini as PID 1 (signal forwarding + zombie reaping)
  • Standard tooling the example wrappers use: jq, sqlite3, curl, git, python3
  • Non-root agent user (uid 1000, gid 1000) matching the typical host user

No SynapBus binary lives in the image. Agents reach the SynapBus MCP server on the host at host.docker.internal:<port> — the harness rewrites .gemini/settings.json URLs from 127.0.0.1 to the gateway hostname automatically.

Build

Local single-arch:

docker build -t synapbus-agent:latest image-build/synapbus-agent

Multi-arch via buildx (recommended for sharing the image):

docker buildx build \
    --platform linux/amd64,linux/arm64 \
    -t synapbus-agent:latest \
    --load \
    image-build/synapbus-agent

Pin specific CLI versions with build args:

docker build \
    --build-arg GEMINI_CLI_VERSION=0.37.1 \
    --build-arg CLAUDE_CODE_VERSION=1.0.0 \
    -t synapbus-agent:0.37.1 \
    image-build/synapbus-agent

Wire an agent to use it

In harness_config_json add a docker block:

{
  "gemini_md": "...",
  "mcp_servers": [...],
  "env": {...},
  "docker": {
    "image": "synapbus-agent:latest",
    "memory": "1g",
    "cpus": "1.0",
    "network": "bridge"
  }
}

The reactor will pick the docker backend automatically when it sees the docker.image field. Default security posture: --cap-drop=ALL, --security-opt=no-new-privileges, --read-only root with tmpfs /tmp, --pids-limit=512, --user=<host uid:gid>. Override via the typed fields in the docker block (memory, cpus, cap_add, extra_mounts, read_only_root, user).