social-mi-bi/docker-compose.yml
Dave Porter fb5acdb892 Initial commit: social MI/BI multi-agent reporting tool
4-stage agent pipeline (Data Mapper, Input Collector, Strategy Writer, Report
Builder) with React wizard, Postgres persistence, HITL + YOLO modes, Apify
embed hydration, clone-for-next-month, and slide-deck HTML output.

Proven end-to-end against real Cif Meltwater data (Instagram + TikTok) with
Anthropic Opus 4.7 (strategy) and Sonnet 4.6 (report builder).
2026-04-17 17:07:44 -04:00

185 lines
6.1 KiB
YAML

services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
ports:
- "${POSTGRES_PORT}:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 5s
timeout: 3s
retries: 20
redis:
image: redis:7-alpine
ports:
- "${REDIS_PORT}:6379"
volumes:
- redis-data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 3s
retries: 20
minio:
image: minio/minio:latest
command: server /data --console-address ":9001"
environment:
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
ports:
- "${MINIO_PORT}:9000"
- "${MINIO_CONSOLE_PORT}:9001"
volumes:
- minio-data:/data
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
interval: 5s
timeout: 3s
retries: 20
minio-init:
image: minio/mc:latest
depends_on:
minio:
condition: service_healthy
entrypoint: >
/bin/sh -c "
mc alias set local http://minio:9000 ${MINIO_ROOT_USER} ${MINIO_ROOT_PASSWORD} &&
mc mb --ignore-existing local/${MINIO_BUCKET_UPLOADS} &&
mc mb --ignore-existing local/${MINIO_BUCKET_ARTEFACTS} &&
mc mb --ignore-existing local/${MINIO_BUCKET_REPORTS} &&
echo 'MinIO buckets ready.'
"
api:
build:
context: .
dockerfile: infra/api.Dockerfile
command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
environment:
- APP_ENV=${APP_ENV}
- LOG_LEVEL=${LOG_LEVEL}
- DATABASE_URL=${DATABASE_URL}
- ALEMBIC_DATABASE_URL=${ALEMBIC_DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- MINIO_ENDPOINT=${MINIO_ENDPOINT}
- MINIO_PUBLIC_ENDPOINT=${MINIO_PUBLIC_ENDPOINT}
- MINIO_REGION=${MINIO_REGION}
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- MINIO_BUCKET_UPLOADS=${MINIO_BUCKET_UPLOADS}
- MINIO_BUCKET_ARTEFACTS=${MINIO_BUCKET_ARTEFACTS}
- MINIO_BUCKET_REPORTS=${MINIO_BUCKET_REPORTS}
- SESSION_SECRET=${SESSION_SECRET}
- SESSION_COOKIE_NAME=${SESSION_COOKIE_NAME}
- SESSION_MAX_AGE_SECONDS=${SESSION_MAX_AGE_SECONDS}
- BOOTSTRAP_ADMIN_EMAIL=${BOOTSTRAP_ADMIN_EMAIL}
- BOOTSTRAP_ADMIN_PASSWORD=${BOOTSTRAP_ADMIN_PASSWORD}
- BOOTSTRAP_ADMIN_NAME=${BOOTSTRAP_ADMIN_NAME}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- ANTHROPIC_MODEL_DATA_MAPPER=${ANTHROPIC_MODEL_DATA_MAPPER}
- ANTHROPIC_MODEL_INPUT_COLLECTOR=${ANTHROPIC_MODEL_INPUT_COLLECTOR}
- ANTHROPIC_MODEL_STRATEGY_WRITER=${ANTHROPIC_MODEL_STRATEGY_WRITER}
- ANTHROPIC_MODEL_REPORT_BUILDER=${ANTHROPIC_MODEL_REPORT_BUILDER}
- ANTHROPIC_MAX_OUTPUT_TOKENS=${ANTHROPIC_MAX_OUTPUT_TOKENS}
- APIFY_API_TOKEN=${APIFY_API_TOKEN}
- APIFY_ACTOR_TIKTOK=${APIFY_ACTOR_TIKTOK}
- APIFY_ACTOR_INSTAGRAM=${APIFY_ACTOR_INSTAGRAM}
- APIFY_CACHE_TTL_HOURS=${APIFY_CACHE_TTL_HOURS}
- APIFY_CAP_CENTS_PER_REPORT=${APIFY_CAP_CENTS_PER_REPORT}
- FRONTEND_ORIGIN=${FRONTEND_ORIGIN}
- API_PUBLIC_URL=${API_PUBLIC_URL}
- REPORT_MAX_HTML_BYTES=${REPORT_MAX_HTML_BYTES}
- TZ=${TZ}
volumes:
- ./backend:/app
- ./Build-Information:/app/Build-Information:ro
ports:
- "${API_PORT}:8000"
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
worker:
build:
context: .
dockerfile: infra/api.Dockerfile
command: arq app.workflow.queue.WorkerSettings
environment:
- APP_ENV=${APP_ENV}
- LOG_LEVEL=${LOG_LEVEL}
- DATABASE_URL=${DATABASE_URL}
- REDIS_URL=${REDIS_URL}
- MINIO_ENDPOINT=${MINIO_ENDPOINT}
- MINIO_PUBLIC_ENDPOINT=${MINIO_PUBLIC_ENDPOINT}
- MINIO_REGION=${MINIO_REGION}
- MINIO_ROOT_USER=${MINIO_ROOT_USER}
- MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD}
- MINIO_BUCKET_UPLOADS=${MINIO_BUCKET_UPLOADS}
- MINIO_BUCKET_ARTEFACTS=${MINIO_BUCKET_ARTEFACTS}
- MINIO_BUCKET_REPORTS=${MINIO_BUCKET_REPORTS}
- SESSION_SECRET=${SESSION_SECRET}
- SESSION_COOKIE_NAME=${SESSION_COOKIE_NAME}
- SESSION_MAX_AGE_SECONDS=${SESSION_MAX_AGE_SECONDS}
- BOOTSTRAP_ADMIN_EMAIL=${BOOTSTRAP_ADMIN_EMAIL}
- BOOTSTRAP_ADMIN_PASSWORD=${BOOTSTRAP_ADMIN_PASSWORD}
- BOOTSTRAP_ADMIN_NAME=${BOOTSTRAP_ADMIN_NAME}
- FRONTEND_ORIGIN=${FRONTEND_ORIGIN}
- API_PUBLIC_URL=${API_PUBLIC_URL}
- ANTHROPIC_API_KEY=${ANTHROPIC_API_KEY}
- ANTHROPIC_MODEL_DATA_MAPPER=${ANTHROPIC_MODEL_DATA_MAPPER}
- ANTHROPIC_MODEL_INPUT_COLLECTOR=${ANTHROPIC_MODEL_INPUT_COLLECTOR}
- ANTHROPIC_MODEL_STRATEGY_WRITER=${ANTHROPIC_MODEL_STRATEGY_WRITER}
- ANTHROPIC_MODEL_REPORT_BUILDER=${ANTHROPIC_MODEL_REPORT_BUILDER}
- ANTHROPIC_MAX_OUTPUT_TOKENS=${ANTHROPIC_MAX_OUTPUT_TOKENS}
- APIFY_API_TOKEN=${APIFY_API_TOKEN}
- APIFY_ACTOR_TIKTOK=${APIFY_ACTOR_TIKTOK}
- APIFY_ACTOR_INSTAGRAM=${APIFY_ACTOR_INSTAGRAM}
- APIFY_CACHE_TTL_HOURS=${APIFY_CACHE_TTL_HOURS}
- APIFY_CAP_CENTS_PER_REPORT=${APIFY_CAP_CENTS_PER_REPORT}
- REPORT_MAX_HTML_BYTES=${REPORT_MAX_HTML_BYTES}
- WORKER_CONCURRENCY=${WORKER_CONCURRENCY}
- TZ=${TZ}
volumes:
- ./backend:/app
- ./Build-Information:/app/Build-Information:ro
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
minio:
condition: service_healthy
web:
build:
context: .
dockerfile: infra/web.Dockerfile
command: npm run dev -- --host 0.0.0.0 --port 5173
environment:
- VITE_API_BASE=${API_PUBLIC_URL}
- VITE_WS_BASE=${API_PUBLIC_URL}
volumes:
- ./frontend:/app
- web-node-modules:/app/node_modules
ports:
- "${WEB_PORT}:5173"
depends_on:
- api
volumes:
pgdata:
redis-data:
minio-data:
web-node-modules: