Paperclip ships as a Docker image, making containerized deployment the standard path for both development and production. The Docker setup bundles the Paperclip control plane, agent runtime, and dashboard into a single container (or multi-container compose stack for production). This page covers everything from the initial docker run to a production-ready Docker Compose configuration with persistent storage, proper networking, environment variables, and scaling. If you ran npx paperclipai onboard and chose Docker, this is the reference for what that generated and how to customize it.
Master paperclip docker deployment
Take the Paperclip Setup course with hands-on lessons and challenges.
The simplest way to run Paperclip. Uses SQLite for storage (fine for development, not for production). The -v flag creates a named volume for persistent data. Without it, agent workspaces and memory would be lost on container restart.
Production setup with PostgreSQL for state, Redis for job queues and agent scheduling. Health checks ensure Paperclip waits for PostgreSQL before starting. All secrets come from environment variables (use a .env file locally, Docker secrets in production). Named volumes persist data across container restarts and upgrades.
Environment variables control all Paperclip configuration. PAPERCLIP_SECRET_KEY signs JWTs for dashboard authentication — generate a random string and never share it. CORS_ORIGINS restricts which domains can call the API. Set LOG_LEVEL to 'debug' during initial setup, then 'info' or 'warn' for production.
Caddy provides automatic HTTPS via Let's Encrypt. Route dashboard and API traffic through a single domain with path-based routing. This eliminates the need to expose ports 3000 and 3001 directly — remove those port mappings from the paperclip service after adding Caddy.
Always check release notes before upgrading — some versions require database migrations. The named volumes ensure your data survives the upgrade. Run migrations after restarting the container. Check logs to verify the new version started cleanly.
Running Paperclip in Docker without a persistent volume, losing all agent workspaces, memory, and session data when the container restarts
Always mount a volume to /data: `-v paperclip-data:/data`. This preserves agent configurations (SOUL.md, MEMORY.md), session history, and uploaded files across container restarts and upgrades.
Using SQLite in production, which does not support concurrent writes from multiple agent processes
SQLite is fine for development and single-agent setups. For production with multiple agents running heartbeats and cron jobs concurrently, use PostgreSQL. Set PAPERCLIP_DB_URL to a PostgreSQL connection string.
Exposing the Paperclip API port (3001) directly to the internet without TLS or authentication
Put Paperclip behind a reverse proxy (Caddy, nginx, Traefik) with TLS termination. The API port should only be accessible within the Docker network. Remove the port mapping from docker-compose.yml and route traffic through the proxy.
Hardcoding API keys in docker-compose.yml or Dockerfile instead of using environment variables or Docker secrets
Use a .env file (excluded from version control) for local development and Docker secrets for production. Never commit API keys to your repository — even in a private repo, credentials in git history are a persistent risk.
Paperclip deploys as a Docker container with PostgreSQL for state and Redis for job queues. Use `npx paperclipai onboard` to generate a Docker Compose setup, then customize for production: add persistent volumes, configure environment variables for API keys and secrets, put the dashboard and API behind a reverse proxy with TLS, and pin image versions. Always mount /data for persistent agent workspaces. Use PostgreSQL (not SQLite) for production workloads with concurrent agents.
Interactive lessons and challenges on Stanza, practice in VS Code, Cursor, or the web.
Interactive lessons and challenges, right in your code editor.
Check the free courses. No credit card.