services: db: image: postgres:16-alpine environment: POSTGRES_DB: bluesky POSTGRES_USER: ${POSTGRES_USER:-bluesky} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme} volumes: - pgdata:/var/lib/postgresql/data - ./scripts/init.sql:/docker-entrypoint-initdb.d/01-init.sql ports: - "${POSTGRES_PORT:-5432}:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-bluesky}"] interval: 5s retries: 5 restart: unless-stopped collector: build: . depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql://${POSTGRES_USER:-bluesky}:${POSTGRES_PASSWORD:-changeme}@db:5432/bluesky BSKY_PUBLIC_API: https://public.api.bsky.app LOG_LEVEL: ${LOG_LEVEL:-INFO} MAX_PAGES_PER_ACCOUNT: ${MAX_PAGES_PER_ACCOUNT:-50} MENTION_LOOKBACK_HOURS: ${MENTION_LOOKBACK_HOURS:-12} BSKY_HANDLE: ${BSKY_HANDLE:-} BSKY_APP_PASSWORD: ${BSKY_APP_PASSWORD:-} LLM_API_KEY: ${LLM_API_KEY:-} ANALYZER_MODEL: ${ANALYZER_MODEL:-gpt-4.1-nano} ANALYZER_CONCURRENCY: ${ANALYZER_CONCURRENCY:-3} ANALYZER_BATCH_SIZE: ${ANALYZER_BATCH_SIZE:-10} ANALYZER_LIMIT: ${ANALYZER_LIMIT:-0} volumes: - ./config:/app/config:ro - ./logs:/app/logs - ./scripts:/app/scripts:ro labels: ofelia.enabled: "true" ofelia.job-exec.collect.schedule: "0 0 */4 * * *" ofelia.job-exec.collect.command: "python -m src" ofelia.job-exec.analyze.schedule: "0 30 */4 * * *" ofelia.job-exec.analyze.command: "python -m src.analyzer" restart: unless-stopped scheduler: image: mcuadros/ofelia:latest depends_on: - collector command: daemon --docker volumes: - /var/run/docker.sock:/var/run/docker.sock:ro restart: unless-stopped web: build: context: . dockerfile: web.Dockerfile depends_on: db: condition: service_healthy environment: DATABASE_URL: postgresql://${POSTGRES_USER:-bluesky}:${POSTGRES_PASSWORD:-changeme}@db:5432/bluesky ports: - "${WEB_PORT:-5001}:5001" restart: unless-stopped volumes: pgdata: