nginx-proxy (new role): - Shared nginx + certbot under /opt/nginx, replacing the copies that lived inside the Paperclip compose project - Apps publish via tasks_from: add_vhost (cert marker -> issue cert -> write vhost -> nginx -t -> reload); a vhost that fails nginx -t is rolled back - Certs issued one per domain via Cloudflare DNS challenge; domains registered as marker files in cert-domains/; optional LE staging - Stock nginx.conf plus conf.d (directory mounts, not single-file mounts); catch-all server drops unknown Host/SNI - Containers renamed to nginx and certbot hermes_docker (new role): - Official Hermes image, host networking, gateway and dashboard bound to loopback and published through nginx-proxy - Dashboard login via basic-auth provider, secrets from the vault - Main model set from hermes_model (fantasmic endpoint, key from vault); config.yaml overrides are merged from a 0600 staged file that is removed afterwards, so the key never appears in a command line - Data dir owner-only (HERMES_HOME_MODE=0700) paperclip-docker: - Remove nginx, certbot and docker-compose download tasks; deploy with community.docker.docker_compose_v2 (idempotent, remove_orphans) - Stop passing the Cloudflare token and certbot email to the Paperclip container via env_file - Bind Postgres to 127.0.0.1 (host networking exposed it on all interfaces); stop chowning pgdata, which the postgres image owns - Handler recreates the paperclip service so .env changes apply - Domain m-v.wdw-labs.cloud -> cranium-command.wdw-labs.cloud Playbooks: - Add day1_deploy_nginx_proxy.yml and day1_deploy_hermes_docker.yml - deploy_paperclip_stack.yml: run nginx-proxy before paperclip-docker, CLI-based container checks (no Docker SDK dependency) - Remove deploy-hermes.yml Host vars: add nginx_proxy_certbot_email and nginx_proxy_certbot_staging (staging stays on until the switch to real certs).
55 lines
1.9 KiB
Django/Jinja
55 lines
1.9 KiB
Django/Jinja
services:
|
|
db:
|
|
image: postgres:16-alpine
|
|
container_name: paperclip-db
|
|
network_mode: host
|
|
# network_mode: host would otherwise expose Postgres on every interface
|
|
command: ["postgres", "-c", "listen_addresses=127.0.0.1"]
|
|
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: {{ paperclip_listen_host }}
|
|
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
|