* fix(deploy): pass CADDY_TLS through to caddy container PR #52 added the {$CADDY_TLS:default} substitution to the Caddyfile but forgot to expose CADDY_TLS to the caddy service in docker-compose.yml. Result: Caddyfile substitution falls back to the default (`tls /certs/fullchain.pem /certs/privkey.pem`) regardless of what the operator wrote into .env, and Caddy crash-loops with "open /certs/fullchain.pem: no such file or directory" on any LE / internal deployment. Compose `- CADDY_TLS` (no `=value`) is the bare-form passthrough — Compose reads the value from .env (or the host shell) at up time. No-op when CADDY_TLS is unset (Caddyfile default kicks in), exact behavior preserved for cert-file deployments. Caught by Keboola's first agnes-dev recreate (kids-ai-data-analysis project, agnes-dev.keboola.com) — VM came up with .env containing CADDY_TLS="tls petr@keboola.com" but Caddy ignored it and tried to load the corp PKI cert file. * docs(changelog): document the CADDY_TLS passthrough fix per discipline rule
146 lines
3.7 KiB
YAML
146 lines
3.7 KiB
YAML
services:
|
|
app:
|
|
build: .
|
|
# --proxy-headers + --forwarded-allow-ips make uvicorn honor the
|
|
# X-Forwarded-Proto / X-Forwarded-Host headers any reverse proxy (Caddy,
|
|
# nginx, Cloudflare Tunnel) sets. Without it, request.url_for() emits
|
|
# http://localhost:8000/... even when the user is on https://, which
|
|
# breaks OAuth callbacks (redirect_uri_mismatch). Belt-and-suspenders —
|
|
# FORWARDED_ALLOW_IPS=* in .env does the same via env var.
|
|
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --proxy-headers --forwarded-allow-ips='*'
|
|
ports:
|
|
- "8000:8000"
|
|
volumes:
|
|
- data:/data
|
|
- ./config:/app/config:ro
|
|
# - ./custom-connectors:/app/connectors/custom:ro # Tier A: AI-generated connectors
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
healthcheck:
|
|
test: ["CMD", "curl", "-sf", "http://localhost:8000/api/health"]
|
|
interval: 30s
|
|
timeout: 5s
|
|
retries: 3
|
|
restart: unless-stopped
|
|
|
|
# One-shot: run extractor then rebuild orchestrator views
|
|
extract:
|
|
build: .
|
|
command: >
|
|
sh -c "python -m connectors.keboola.extractor &&
|
|
python -c 'from src.orchestrator import SyncOrchestrator; print(SyncOrchestrator().rebuild())'"
|
|
volumes:
|
|
- data:/data
|
|
- ./config:/app/config:ro
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
profiles:
|
|
- extract
|
|
|
|
scheduler:
|
|
build: .
|
|
command: python -m services.scheduler
|
|
volumes:
|
|
- data:/data
|
|
- ./config:/app/config:ro
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
- API_URL=http://app:8000
|
|
- SEED_ADMIN_EMAIL=${SEED_ADMIN_EMAIL:-}
|
|
depends_on:
|
|
app:
|
|
condition: service_healthy
|
|
restart: unless-stopped
|
|
|
|
telegram-bot:
|
|
build: .
|
|
command: python -m services.telegram_bot
|
|
volumes:
|
|
- data:/data
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
depends_on:
|
|
- app
|
|
profiles:
|
|
- full
|
|
restart: unless-stopped
|
|
|
|
ws-gateway:
|
|
build: .
|
|
command: python -m services.ws_gateway
|
|
volumes:
|
|
- data:/data
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
depends_on:
|
|
- app
|
|
profiles:
|
|
- full
|
|
restart: unless-stopped
|
|
|
|
corporate-memory:
|
|
build: .
|
|
command: python -m services.corporate_memory
|
|
volumes:
|
|
- data:/data
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
depends_on:
|
|
- app
|
|
profiles:
|
|
- full
|
|
restart: unless-stopped
|
|
|
|
session-collector:
|
|
build: .
|
|
command: python -m services.session_collector
|
|
volumes:
|
|
- data:/data
|
|
env_file: .env
|
|
environment:
|
|
- DATA_DIR=/data
|
|
depends_on:
|
|
- app
|
|
profiles:
|
|
- full
|
|
restart: unless-stopped
|
|
|
|
# TLS reverse proxy. Corporate-CA certs mounted from /data/state/certs
|
|
# (managed by scripts/grpn/agnes-tls-rotate.sh on the VM). For local
|
|
# development without certs, run without --profile tls and hit :8000
|
|
# directly.
|
|
caddy:
|
|
image: caddy:2-alpine
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
volumes:
|
|
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
|
- /data/state/certs:/certs:ro
|
|
- caddy_data:/data
|
|
- caddy_config:/config
|
|
environment:
|
|
- DOMAIN=${DOMAIN:-localhost}
|
|
# Passes through whatever the operator set in .env. Caddyfile uses
|
|
# {$CADDY_TLS:tls /certs/fullchain.pem /certs/privkey.pem} so:
|
|
# - unset → cert-file mode (corp PKI rotated by tls-rotate.sh)
|
|
# - "tls <email>" → Let's Encrypt auto-issue
|
|
# - "tls internal" → Caddy-managed self-signed
|
|
- CADDY_TLS
|
|
depends_on:
|
|
app:
|
|
condition: service_healthy
|
|
restart: unless-stopped
|
|
profiles:
|
|
- tls
|
|
|
|
volumes:
|
|
data:
|
|
caddy_data:
|
|
caddy_config:
|