The two per-run limiters in main.py now read from the environment with their current hardcoded values as defaults. Lets us tune cadence (e.g. 200 → 500 newly-tagged files per click) without rebuilding the image — edit .env and `docker compose up -d --force-recreate api`. docker-compose.yml threads both vars into the api container. .env.example documents them with empty defaults. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
77 lines
3.7 KiB
YAML
77 lines
3.7 KiB
YAML
# Per ~/.claude/CLAUDE.md Docker policy: every compose file must pin a unique
|
|
# top-level `name:` so multiple apps sharing a server (or `deploy/` parent dir)
|
|
# don't collide on container/volume names.
|
|
name: marriott-tagging
|
|
|
|
services:
|
|
db:
|
|
image: postgres:16
|
|
restart: unless-stopped
|
|
environment:
|
|
POSTGRES_USER: ${POSTGRES_USER:-marriott}
|
|
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-marriott}
|
|
POSTGRES_DB: ${POSTGRES_DB:-marriott_tagging}
|
|
# 127.0.0.1: binding — Postgres must NOT be reachable from outside the
|
|
# host. On the dev server this prevents the DB from sitting on the
|
|
# public internet; on a local mac it's a no-op for `psql` from the
|
|
# same machine. Pick a non-default port via $POSTGRES_HOST_PORT if
|
|
# 5432 is taken locally (the deploy script auto-picks on the server).
|
|
ports:
|
|
- "127.0.0.1:${POSTGRES_HOST_PORT:-5432}:5432"
|
|
volumes:
|
|
- pgdata:/var/lib/postgresql/data
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-marriott} -d ${POSTGRES_DB:-marriott_tagging}"]
|
|
interval: 5s
|
|
timeout: 5s
|
|
retries: 10
|
|
|
|
# ── Manual-only mode ─────────────────────────────────────────────────────────
|
|
# The nightly APScheduler container (`tagger`) was intentionally removed so the
|
|
# app only runs Gemini against new files when a human clicks "Run now" in the
|
|
# SPA (or `curl -X POST .../api/runs`). The pipeline still lives in main.py
|
|
# and scheduler.py is kept in the repo — re-add a `tagger` service here using
|
|
# the previous block in git history if you want cron-driven passes back.
|
|
|
|
api:
|
|
build: .
|
|
restart: unless-stopped
|
|
depends_on:
|
|
db:
|
|
condition: service_healthy
|
|
environment:
|
|
DATABASE_URL: postgresql://${POSTGRES_USER:-marriott}:${POSTGRES_PASSWORD:-marriott}@db:5432/${POSTGRES_DB:-marriott_tagging}
|
|
GEMINI_API_KEY: ${GEMINI_API_KEY}
|
|
# One or more Box folder IDs to walk recursively (comma-separated).
|
|
# Empty → falls back to the hardcoded default in main.py.
|
|
BOX_FOLDER_IDS: ${BOX_FOLDER_IDS:-}
|
|
# Per-run caps (newly-tagged file count and wall-clock seconds). Defaults
|
|
# in main.py are 200 and 14400 (4h); override here to tune without a rebuild.
|
|
MAX_FILES_PER_RUN: ${MAX_FILES_PER_RUN:-}
|
|
MAX_RUN_DURATION_SECS: ${MAX_RUN_DURATION_SECS:-}
|
|
TZ: ${TZ:-UTC}
|
|
# Auth — set DEV_AUTH_BYPASS=true to skip MSAL while you wire it up.
|
|
DEV_AUTH_BYPASS: ${DEV_AUTH_BYPASS:-true}
|
|
AZURE_TENANT_ID: ${AZURE_TENANT_ID:-}
|
|
AZURE_CLIENT_ID: ${AZURE_CLIENT_ID:-}
|
|
# Comma-separated list of admin emails — only these accounts can hit
|
|
# POST /api/runs and POST /api/backfill. Everyone else is read-only.
|
|
ADMIN_EMAILS: ${ADMIN_EMAILS:-}
|
|
DEV_AUTH_EMAIL: ${DEV_AUTH_EMAIL:-dev@oliver.agency}
|
|
DEV_AUTH_NAME: ${DEV_AUTH_NAME:-Dev User}
|
|
# In DEV_AUTH_BYPASS mode the dev user is admin by default; flip to
|
|
# false here if you want to test the non-admin UX without enabling SSO.
|
|
DEV_AUTH_IS_ADMIN: ${DEV_AUTH_IS_ADMIN:-true}
|
|
# CORS for local dev: when Vite is on :5173 and FastAPI on host:8004.
|
|
# Empty in prod — Apache serves SPA and API under the same origin.
|
|
CORS_ORIGINS: ${CORS_ORIGINS:-}
|
|
command: ["uvicorn", "api:app", "--host", "0.0.0.0", "--port", "8000"]
|
|
ports:
|
|
- "127.0.0.1:${MARRIOTT_API_PORT:-8004}:8000"
|
|
volumes:
|
|
# The API may trigger a tagging pass via /api/runs, which calls into the
|
|
# same Box+Gemini pipeline → it needs the same JWT config.
|
|
- ./box_config.json:/app/box_config.json:ro
|
|
|
|
volumes:
|
|
pgdata:
|