Files
Darren Davison 9802636be3 build(docker): bundle Gemini CLI in image for gemini_local adapter (#7693)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work, and it runs agents through pluggable adapters.
> - One of those adapters, `gemini_local`
(`packages/adapters/gemini-local/`), runs Google's Gemini CLI on the
same host as the server.
> - For local (in-container) execution, the adapter only probes `PATH`
for the binary (`packages/adapter-utils/src/execution-target.ts`); it
does **not** auto-install — only `sandbox` transport targets install on
demand via `SANDBOX_INSTALL_COMMAND`.
> - The production Docker image bakes in `claude`, `codex`, and
`opencode` so their `*_local` adapters work out of the box, but `gemini`
was never added — so `gemini_local` fails inside the container with a
missing-binary error.
> - This PR adds `@google/gemini-cli@latest` to the image's global
install so `gemini_local` works locally like the other bundled CLIs,
sets `GEMINI_SANDBOX=false` for safe in-container CLI use, and documents
all bundled CLIs.
> - The benefit is plug-and-play Gemini support in Docker with no
per-deployment CLI install step, plus accurate docs (including a
previously-undocumented `opencode` bundle) and a heads-up about Google's
imminent unrestricted-API-key block.

## Linked Issues or Issue Description

No existing issue. Following the **adapter/feature** template fields:

- **Capability:** Run the existing `gemini_local` adapter inside the
official Docker image without a manual CLI install.
- **Problem/motivation:** The image pre-installs `claude`, `codex`, and
`opencode`, but not `gemini`. Because local execution probes `PATH` and
never auto-installs (only sandbox targets do), `gemini_local` runs fail
in-container with a missing-binary error. Operators currently have to
maintain a forked image.
- **Proposed solution:** Add `@google/gemini-cli@latest` to the existing
global `npm install` line; set `GEMINI_SANDBOX=false` in `ENV`.
- **Alternatives considered:** Runtime install at container start
(slower, network-dependent, inconsistent with how the other three CLIs
are handled).

**Related / superseded PRs** (both make the same Dockerfile change and
can be closed if this merges):
- #5912 — `fix(docker): install gemini-cli and normalize persistent
volume permissions`. Same Dockerfile line, but also bundles unrelated
volume-permission and heartbeat-test changes, and a maintainer noted it
now has a merge conflict. I corrected Greptile's `GEMINI_SANDBOX`
reasoning there and it was re-scored 5/5 (see [resolved
thread](https://github.com/paperclipai/paperclip/pull/5912#discussion_r3367332785))
— this PR is the rebased, docs-complete, single-purpose version of that
change.
- #2731 — `Added @google/gemini-cli to the Dockerfile`. One-liner, now
stale and merge-conflicting (predates the `opencode-ai` addition).

> **Note for Greptile:** the `--sandbox=none` reasoning for the Gemini
CLI sandbox concern was already validated on #5912's `Dockerfile:59`
thread and accepted (re-scored 5/5). This PR additionally bakes
`GEMINI_SANDBOX=false` into `ENV` as defense-in-depth, so the concern is
covered both at the adapter layer and the image layer.

## What Changed

- **Dockerfile:** add `@google/gemini-cli@latest` to the production
global npm install (after `opencode-ai`).
- **Dockerfile:** add `GEMINI_SANDBOX=false` to the `ENV` block (matches
the existing `OPENCODE_ALLOW_ALL_MODELS=true` precedent) so a
manually-invoked `gemini` inside the container does not attempt a
Docker-in-Docker sandbox.
- **docs/deploy/docker.md:** rename the section to "Local Adapter CLIs
in Docker"; list all four bundled CLIs mapped to their adapter type keys
(fixes a pre-existing gap — `opencode` was bundled but undocumented);
add `GEMINI_API_KEY` to the example; document per-provider credentials,
the `GEMINI_SANDBOX=false` default, and Google's 2026-06-19
unrestricted-key block with the `gemini auth login` (OAuth) alternative.

## Verification

- `npm view @google/gemini-cli` confirms the package exists, provides
the `gemini` bin, and requires Node `>=20` (the base image is Node 22
LTS). 
- Adapter already disables the CLI sandbox per run:
`packages/adapters/gemini-local/src/server/execute.ts` pushes
`--sandbox=none` whenever `config.sandbox` is false (the default). 
- Confirmed neither file was modified on `upstream/master`, so this
rebases cleanly with no conflicts. 
- Full image build is exercised by CI. (I did not run the multi-stage
`docker build` locally; the change adds one package to an existing,
working `npm install` line.)
- Reviewer manual check: `docker build -t paperclip-local . && docker
run --rm paperclip-local gemini --version` should print the CLI version.

## Risks

- **Low risk.** Adds one npm package to an existing global install and
one inert env var; no application code paths change.
- Minor image-size increase from the additional CLI (consistent with the
three already bundled).
- `@latest` is unpinned — intentionally consistent with the sibling
`@anthropic-ai/claude-code@latest` / `@openai/codex@latest` on the same
line; pinning all of them is a separate decision out of scope here.

## Model Used

Claude Opus 4.8 (model ID `claude-opus-4-8`, 1M-context variant), via
Claude Code with tool use / agentic file editing and web research.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues OR (b) described the
issue in-PR following the relevant issue template
- [ ] I have run tests locally and they pass (no unit tests cover the
Dockerfile; package/bin/engine verified via `npm view`, full build runs
in CI)
- [ ] I have added or updated tests where applicable (N/A — Docker image
+ docs change)
- [ ] If this change affects the UI, I have included before/after
screenshots (N/A)
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green (pending CI run on this PR)
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
(pending review)
- [x] I will address all Greptile and reviewer comments before
requesting merge

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 10:42:07 -07:00
..