services: redlib: image: tagliasteel/redlib:latest restart: unless-stopped read_only: true security_opt: - no-new-privileges:true cap_drop: - ALL env_file: - redlib.env expose: - "8080" networks: - redlib healthcheck: test: ["CMD", "wget", "--spider", "-q", "--tries=1", "http://localhost:8080/settings"] interval: 30s timeout: 5s retries: 3 decider: build: context: . dockerfile: Dockerfile.decider restart: unless-stopped volumes: - decider_model_cache:/root/.cache/huggingface expose: - "8099" networks: - redlib healthcheck: test: ["CMD", "uv", "run", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8099/health')"] interval: 30s timeout: 10s retries: 10 start_period: 10m proxy: build: context: . dockerfile: Dockerfile.proxy restart: unless-stopped volumes: - proxy_decision_cache:/data environment: REDLIB_URL: http://redlib:8080 DECIDER_URL: http://decider:8099 DECISION_PROVIDER: ${DECISION_PROVIDER:-local} CODEX_ADAPTER_URL: ${CODEX_ADAPTER_URL:-http://host.docker.internal:8098} OPENAI_API_KEY: ${OPENAI_API_KEY:-} OPENAI_BASE_URL: ${OPENAI_BASE_URL:-https://api.openai.com/v1} OPENAI_MODEL: ${OPENAI_MODEL:-gpt-6-luna} CLOUDFLARE_ACCOUNT_ID: ${CLOUDFLARE_ACCOUNT_ID:-} CLOUDFLARE_API_TOKEN: ${CLOUDFLARE_API_TOKEN:-} CLOUDFLARE_MODEL: ${CLOUDFLARE_MODEL:-clef-flash} ALLOWED_THRESHOLD: ${ALLOWED_THRESHOLD:-0.50} FILTER_EXCLUDED_TOPICS: ${FILTER_EXCLUDED_TOPICS:-politics,death or grief,divorce or breakups,cute animals} DECIDER_TIMEOUT: ${DECIDER_TIMEOUT:-20} DECISION_CACHE_SIZE: ${DECISION_CACHE_SIZE:-512} DECISION_DB: ${DECISION_DB:-/data/decisions.sqlite3} DECIDER_CONCURRENCY: ${DECIDER_CONCURRENCY:-16} depends_on: redlib: condition: service_healthy decider: condition: service_healthy ports: - "127.0.0.1:${PROXY_PORT:-8080}:8080" networks: - redlib volumes: decider_model_cache: proxy_decision_cache: networks: redlib: driver: bridge