Files
PaperClipAI/docker/docker-compose.quickstart.yml
T
Huanyi Xie 95692b7785 fix(docker): forward tool action signing secret in Compose (#15202)
## Thinking Path

> - Paperclip can run through Docker Compose.
> - Approval-gated tools need an independent signing secret.
> - The guide sets that secret before starting Compose.
> - Neither Compose file passes it into the container.
> - This pull request forwards the operator's configured secret.
> - Documented setup can issue signed tool-action approvals.

## Linked Issues or Issue Description

Fixes: #15064

## What Changed

- Forward PAPERCLIP_TOOL_ACTION_SIGNING_SECRET in both shipped Compose
environments.
- Document persistent deployment secrets and reuse on restart.
- Explain that it is independent from the session secret.
- Keep an empty default so deployments without approval-gated tools
retain their existing startup behavior.

## Verification

- Docker Compose config before the fix drops a supplied synthetic secret
in both files.
- After the fix, both preserve the supplied value.
- Both also resolve successfully when the optional signing secret is
absent.
- Used --env-file /dev/null and synthetic values. No containers were
started.
- `node --test scripts/docker-compose-secrets.test.mjs`: 2 passed.
- The Docker context CI lane runs this integration test.
- git diff --check passes.

## Risks

The value is visible to the container as intended. Operators must
protect it as a secret. This does not change admission rules or require
a new startup value for existing deployments.

## Model Used

OpenAI Codex, based on GPT-6, assisted with source review,
implementation and local test execution. The exact deployment model ID
and context-window size are not exposed in this session.

## 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 with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (targeted local checks and
full remote CI pass)
- [x] I have added or updated tests where applicable (Hermes regression
/ real Compose interpolation checks)
- [x] I have updated relevant documentation to reflect my changes
(Hermes has no configuration changes; Compose documentation is updated)
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge
2026-10-15 10:03:01 -07:00

51 lines
2.3 KiB
YAML

# Quickstart: single-container Paperclip with embedded database.
# Copy this file and set the required env vars before running.
#
# cd docker
# Set BETTER_AUTH_SECRET and PAPERCLIP_TOOL_ACTION_SIGNING_SECRET in .env
# once, using a separate `openssl rand -hex 32` value for each. Reuse them
# on restarts; do not replace existing deployment secrets.
# export ANTHROPIC_API_KEY="sk-ant-..."
# docker compose -f docker-compose.quickstart.yml up --build
#
services:
paperclip:
build:
context: ..
dockerfile: Dockerfile
# Ceiling on processes. The image makes tini PID 1 so orphaned agent
# descendants are reaped instead of piling up as zombies; this is the
# backstop if something leaks anyway — the container hits its own limit and
# dies visibly rather than starving the host of pids.
pids_limit: 2048
# Includes the shared 30s adapter-settlement window and final cleanup.
stop_grace_period: 90s
ports:
- "${PAPERCLIP_PORT:-3100}:3100"
environment:
HOST: "0.0.0.0"
PAPERCLIP_HOME: "/paperclip"
# ── LLM provider keys (at least one is needed for agents to work) ──
OPENAI_API_KEY: "${OPENAI_API_KEY:-}"
ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY:-}"
# ── Deployment settings ──
# "authenticated" requires login, "local_trusted" skips auth
PAPERCLIP_DEPLOYMENT_MODE: "authenticated"
# "private" = LAN only, "public" = internet-facing (use with TLS)
PAPERCLIP_DEPLOYMENT_EXPOSURE: "private"
# Base URL users will access the UI at
PAPERCLIP_PUBLIC_URL: "${PAPERCLIP_PUBLIC_URL:-http://localhost:3100}"
# Extra hostnames the instance accepts beyond the public URL host
# (LAN or Tailscale aliases), comma-separated; empty means none
PAPERCLIP_ALLOWED_HOSTNAMES: "${PAPERCLIP_ALLOWED_HOSTNAMES:-}"
# ── Required secret for session signing (generate with: openssl rand -hex 32) ──
BETTER_AUTH_SECRET: "${BETTER_AUTH_SECRET:?BETTER_AUTH_SECRET must be set}"
# Independent secret for signed approval-gated tool actions.
PAPERCLIP_TOOL_ACTION_SIGNING_SECRET: "${PAPERCLIP_TOOL_ACTION_SIGNING_SECRET:-}"
volumes:
# Persistent data directory (database, agent workspaces, uploads)
- "${PAPERCLIP_DATA_DIR:-../data/docker-paperclip}:/paperclip"