chore(agent): docker cleanups for the sandbox-agent sidecar#4745
chore(agent): docker cleanups for the sandbox-agent sidecar#4745mmabrouk wants to merge 1 commit into
Conversation
- Add a production, credential-free sidecar Dockerfile (services/agent/docker/Dockerfile): bakes Pi (MIT), never bakes Claude Code or any credential, runs src/server.ts without a watcher. Verified to build and serve /health. - Add services/agent/docker/README.md documenting the image licensing posture (bake Pi, never bake or distribute Claude Code, install Claude from Anthropic at runtime) and the API-key vs self-host OAuth auth paths. - Record the recipe-not-image posture on the Daytona snapshot builder docstring and the docker-compose comment (we ship the build recipe, not a Claude-containing image).
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 7d897969-f27b-477c-96b8-a0410d50701c
📒 Files selected for processing (4)
docs/design/agent-workflows/scratch/wp-8-rivet-acp-runtime/poc/build_rivet_snapshot.pyhosting/docker-compose/ee/docker-compose.dev.ymlservices/agent/docker/Dockerfileservices/agent/docker/README.md
| FROM node:24-slim | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # CA certificates: the sandbox-agent daemon (Rust) downloads harness CLIs (e.g. Claude | ||
| # Code) over HTTPS using the system trust store, which node:*-slim omits — without this | ||
| # the daemon's `install-agent claude` fails TLS verification. git lets npm/installers | ||
| # fetch git deps. | ||
| RUN apt-get update \ | ||
| && apt-get install -y --no-install-recommends ca-certificates git \ | ||
| && rm -rf /var/lib/apt/lists/* | ||
|
|
||
| RUN corepack enable | ||
|
|
||
| # Install deps as a cached layer (manifest + lockfile only). The full dependency set is | ||
| # installed (not --prod): the runtime uses `tsx` and the extension build uses `esbuild`, | ||
| # both devDependencies. | ||
| COPY package.json pnpm-lock.yaml ./ | ||
| RUN pnpm install --frozen-lockfile | ||
|
|
||
| # Bake the source (no bind mount in production). | ||
| COPY tsconfig.json ./ | ||
| COPY scripts ./scripts | ||
| COPY src ./src | ||
| COPY config ./config | ||
| COPY skills ./skills | ||
|
|
||
| # Bundle the Agenta Pi extension (tracing + tools) into dist/. runSandboxAgent installs | ||
| # this baked copy into Pi's agent dir on every run. Rebuild the image after editing | ||
| # src/extensions/agenta.ts or the tracer. | ||
| RUN pnpm run build:extension | ||
|
|
||
| ENV NODE_ENV=production \ | ||
| PORT=8765 | ||
|
|
||
| EXPOSE 8765 | ||
|
|
||
| # Call the local tsx binary directly to avoid pnpm/corepack HOME writes when the | ||
| # container runs as a non-root host uid. | ||
| CMD ["node_modules/.bin/tsx", "src/server.ts"] |
There was a problem hiding this comment.
Critical: Add a non-root USER directive to fix Trivy DS-0002 security issue.
The Dockerfile runs as root by default (no USER directive), which is a significant container security risk. Additionally, the comment on lines 53–54 assumes non-root execution to avoid pnpm/corepack HOME writes, but no non-root user is created, so this assumption is violated.
Add a USER directive before the final CMD to run the container as a non-root user (e.g., node, or a custom user if needed for permission isolation). Ensure the application directory and any runtime-modified paths are readable/writable by that user.
🔒 Proposed fix: Add USER directive
# Call the local tsx binary directly to avoid pnpm/corepack HOME writes when the
# container runs as a non-root host uid.
+USER node
CMD ["node_modules/.bin/tsx", "src/server.ts"]Note: Verify that the node user (provided by the node:24-slim base image) has read access to /app and write access to any runtime-created directories (e.g., agent state, logs, or cache). If permission issues arise, ensure the build step either changes ownership or sets permissive directory modes.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| FROM node:24-slim | |
| WORKDIR /app | |
| # CA certificates: the sandbox-agent daemon (Rust) downloads harness CLIs (e.g. Claude | |
| # Code) over HTTPS using the system trust store, which node:*-slim omits — without this | |
| # the daemon's `install-agent claude` fails TLS verification. git lets npm/installers | |
| # fetch git deps. | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends ca-certificates git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| RUN corepack enable | |
| # Install deps as a cached layer (manifest + lockfile only). The full dependency set is | |
| # installed (not --prod): the runtime uses `tsx` and the extension build uses `esbuild`, | |
| # both devDependencies. | |
| COPY package.json pnpm-lock.yaml ./ | |
| RUN pnpm install --frozen-lockfile | |
| # Bake the source (no bind mount in production). | |
| COPY tsconfig.json ./ | |
| COPY scripts ./scripts | |
| COPY src ./src | |
| COPY config ./config | |
| COPY skills ./skills | |
| # Bundle the Agenta Pi extension (tracing + tools) into dist/. runSandboxAgent installs | |
| # this baked copy into Pi's agent dir on every run. Rebuild the image after editing | |
| # src/extensions/agenta.ts or the tracer. | |
| RUN pnpm run build:extension | |
| ENV NODE_ENV=production \ | |
| PORT=8765 | |
| EXPOSE 8765 | |
| # Call the local tsx binary directly to avoid pnpm/corepack HOME writes when the | |
| # container runs as a non-root host uid. | |
| CMD ["node_modules/.bin/tsx", "src/server.ts"] | |
| FROM node:24-slim | |
| WORKDIR /app | |
| # CA certificates: the sandbox-agent daemon (Rust) downloads harness CLIs (e.g. Claude | |
| # Code) over HTTPS using the system trust store, which node:*-slim omits — without this | |
| # the daemon's `install-agent claude` fails TLS verification. git lets npm/installers | |
| # fetch git deps. | |
| RUN apt-get update \ | |
| && apt-get install -y --no-install-recommends ca-certificates git \ | |
| && rm -rf /var/lib/apt/lists/* | |
| RUN corepack enable | |
| # Install deps as a cached layer (manifest + lockfile only). The full dependency set is | |
| # installed (not --prod): the runtime uses `tsx` and the extension build uses `esbuild`, | |
| # both devDependencies. | |
| COPY package.json pnpm-lock.yaml ./ | |
| RUN pnpm install --frozen-lockfile | |
| # Bake the source (no bind mount in production). | |
| COPY tsconfig.json ./ | |
| COPY scripts ./scripts | |
| COPY src ./src | |
| COPY config ./config | |
| COPY skills ./skills | |
| # Bundle the Agenta Pi extension (tracing + tools) into dist/. runSandboxAgent installs | |
| # this baked copy into Pi's agent dir on every run. Rebuild the image after editing | |
| # src/extensions/agenta.ts or the tracer. | |
| RUN pnpm run build:extension | |
| ENV NODE_ENV=production \ | |
| PORT=8765 | |
| EXPOSE 8765 | |
| # Call the local tsx binary directly to avoid pnpm/corepack HOME writes when the | |
| # container runs as a non-root host uid. | |
| USER node | |
| CMD ["node_modules/.bin/tsx", "src/server.ts"] |
Source: Linters/SAST tools
Stacked on #(feat/agent-harness-port). Docker/licensing cleanups for the agent sidecar. No app logic changes.
What changed
services/agent/docker/Dockerfile, new). The sidecar only had aDockerfile.dev(tsx watch, bind-mounted source). This adds a credential-free production image: source baked in,NODE_ENV=production, runssrc/server.tswithout a watcher.services/agent/docker/README.md(new) documents the image licensing posture and the two auth paths.Licensing posture this encodes
@earendil-works/pi-coding-agent, MIT) is baked.sandbox-agentdaemon installs it from Anthropic at runtime, keeping Anthropic as the distributor.ANTHROPIC_API_KEY(default, and the only option for cloud/multi-tenant), or a mounted OAuth login for individual self-host use.Verified
pi/pi-acp(MIT) and the Apache-2.0claude-agent-acpadapter, but noclaudebinary, no@anthropic-ai/claude-code, no baked credentials.GET /health→{"status":"ok"}.Deferred (follow-ups)
-fullimage ships the ACP adapters.rivet→sandbox-agentrename is a separate change, intentionally not included here.