# Production Docker Compose for Impri # # Usage (from repo root): # docker compose -f deploy/docker-compose.prod.yml --env-file deploy/.env up -d # # Build context for server is the repo root (workspace lockfile lives there). # Build context for ui is ui/ (its own package.json + vite config). # # Caddy handles TLS termination and reverse-proxies: # api.impri.dev → server:8484 # app.impri.dev → ui:8080 # # Do NOT expose server or ui ports to the host — Caddy is the only ingress. services: server: build: context: .. dockerfile: docker/server.Dockerfile volumes: - impri-data:/app/data environment: DB_PATH: /app/data/impri.db PORT: "8484" HOST: "0.0.0.0" # Public URL of the web inbox — used to construct inbox_url in API responses. BASE_URL: "${BASE_URL:-https://app.impri.dev}" # Security WEBHOOK_SECRET: "${WEBHOOK_SECRET}" # Email notifications (AWS SES via SMTP) SMTP_HOST: "${SMTP_HOST:-}" SMTP_PORT: "${SMTP_PORT:-587}" SMTP_SECURE: "${SMTP_SECURE:-false}" SMTP_USER: "${SMTP_USER:-}" SMTP_PASS: "${SMTP_PASS:-}" SMTP_FROM: "${SMTP_FROM:-}" NOTIFY_EMAIL: "${NOTIFY_EMAIL:-}" # ntfy push notifications NTFY_URL: "${NTFY_URL:-}" NTFY_TOPIC: "${NTFY_TOPIC:-}" # Billing (Stripe) — billing features are gated; server starts fine without these. STRIPE_SECRET_KEY: "${STRIPE_SECRET_KEY:-}" STRIPE_WEBHOOK_SECRET: "${STRIPE_WEBHOOK_SECRET:-}" STRIPE_PRICE_INDIE: "${STRIPE_PRICE_INDIE:-}" STRIPE_PRICE_TEAM: "${STRIPE_PRICE_TEAM:-}" # Set to 1 only on isolated intranet deployments (bypasses SSRF guard). IMPRI_ALLOW_PRIVATE_TARGETS: "${IMPRI_ALLOW_PRIVATE_TARGETS:-}" # Set to 1 to disable the watcher scheduler (approval inbox only mode). DISABLE_WATCHER_SCHEDULER: "${DISABLE_WATCHER_SCHEDULER:-}" restart: unless-stopped healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8484/healthz"] interval: 10s timeout: 5s retries: 3 start_period: 15s networks: - internal ui: build: context: ../ui dockerfile: Dockerfile depends_on: server: condition: service_healthy restart: unless-stopped healthcheck: test: ["CMD", "wget", "-qO-", "http://localhost:8080"] interval: 15s timeout: 5s retries: 3 start_period: 10s networks: - internal caddy: image: caddy:2-alpine ports: - "80:80" - "443:443" - "443:443/udp" # HTTP/3 / QUIC volumes: - ./Caddyfile:/etc/caddy/Caddyfile:ro - caddy-data:/data # TLS certificates (persisted across restarts) - caddy-config:/config # Caddy runtime config environment: # Used by Caddyfile for Let's Encrypt account registration and expiry notices. CADDY_ACME_EMAIL: "${CADDY_ACME_EMAIL:-admin@impri.dev}" depends_on: server: condition: service_healthy ui: condition: service_started restart: unless-stopped networks: - internal volumes: impri-data: # SQLite database. Back this up daily — see deploy/backup.sh. caddy-data: # Let's Encrypt certificates. Losing this means rate-limit delays on next boot. caddy-config: networks: internal: driver: bridge