Files
homelab/ansible/roles/paperclip-docker/templates/docker-compose.yml.j2
T
rblundon d368c92055 feat: Build Paperclip from source instead of published image
- Create playbooks/build_paperclip_image.yml to build image locally from repo
- Clone/update paperclipai/paperclip main branch on deploy host
- Build with --target production for lean, current, self-managed image
- Update docker-compose to use paperclip-local:latest instead of reeoss image
- Gives full control over Paperclip version and dependency updates
- OpenCode v1.2.24 local adapter pre-installed in source build
- Enables rapid iteration and custom patches on Paperclip platform

Deployment flow:
1. ansible-playbook playbooks/build_paperclip_image.yml  # Build from source
2. ansible-playbook playbooks/deploy_paperclip_stack.yml # Deploy with local image
2026-09-27 20:13:02 -05:00

92 lines
2.8 KiB
Django/Jinja

services:
db:
image: postgres:16-alpine
container_name: paperclip-db
network_mode: host
environment:
POSTGRES_USER: paperclip
POSTGRES_PASSWORD: paperclip
POSTGRES_DB: paperclip
volumes:
- {{ paperclip_base_path }}/pgdata:/var/lib/postgresql/data
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U paperclip -d paperclip"]
interval: 10s
timeout: 5s
retries: 5
paperclip:
image: paperclip-local:latest
container_name: paperclip
network_mode: host
env_file:
- {{ paperclip_base_path }}/.env
environment:
HOST: "127.0.0.1"
PAPERCLIP_HOME: /paperclip
PAPERCLIP_PORT: {{ paperclip_port }}
PAPERCLIP_PUBLIC_URL: "https://{{ paperclip_domain }}"
PAPERCLIP_DEPLOYMENT_MODE: "{{ paperclip_deployment_mode }}"
PAPERCLIP_DEPLOYMENT_EXPOSURE: "private"
PAPERCLIP_ALLOWED_HOSTNAMES: "{{ paperclip_allowed_hostnames }}"
DATABASE_URL: "postgresql://paperclip:paperclip@localhost:5432/paperclip"
BETTER_AUTH_SECRET: ${BETTER_AUTH_SECRET}
PAPERCLIP_AGENT_JWT_SECRET: ${PAPERCLIP_AGENT_JWT_SECRET}
VLLM_ENDPOINT: ${VLLM_ENDPOINT}
OPENAI_API_KEY: "${OPENAI_API_KEY:-}"
ANTHROPIC_API_KEY: "${ANTHROPIC_API_KEY:-}"
volumes:
- {{ paperclip_data_dir }}:/paperclip
- {{ paperclip_base_path }}/.config/opencode:/paperclip/.config/opencode
- {{ paperclip_base_path }}/.local/share/opencode:/paperclip/.local/share/opencode
depends_on:
db:
condition: service_healthy
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:{{ paperclip_port }}/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
certbot:
image: certbot/dns-cloudflare:latest
container_name: paperclip-certbot
volumes:
- {{ paperclip_certs_dir }}:/etc/letsencrypt
- {{ paperclip_base_path }}/certbot-init.sh:/certbot-init.sh:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN}
CERTBOT_EMAIL: ${CERTBOT_EMAIL}
PAPERCLIP_DOMAIN: ${PAPERCLIP_DOMAIN}
entrypoint: /bin/sh
command:
- -c
- |
/certbot-init.sh && while true; do certbot renew --quiet; sleep 12h; done
restart: unless-stopped
nginx:
image: nginx:latest
container_name: paperclip-nginx
network_mode: host
volumes:
- {{ paperclip_base_path }}/nginx.conf:/etc/nginx/nginx.conf:ro
- {{ paperclip_certs_dir }}:/etc/nginx/certs:ro
depends_on:
- certbot
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:80/"]
interval: 30s
timeout: 10s
retries: 3
start_period: 30s
volumes:
paperclip_data:
driver: local