services: winnow: image: ghcr.io/sudolulo/winnow:latest container_name: winnow environment: # ── Required ────────────────────────────────────────────────────────── - IMMICH_URL=${IMMICH_URL} - API_KEY=${API_KEY} - FRIGATE_URL=${FRIGATE_URL} # ── Mode & Strategy ─────────────────────────────────────────────────── # Auto mode is active by default when no TTY is present (Docker/cron). # Set AUTO_MODE=true to force auto mode in an interactive terminal. # To run interactively: docker exec -it winnow winnow # - VERBOSE=true # Enable DEBUG-level console output # TRAINING_MODE: face = upload to Frigate face recognition API # object = save crops to output dir for manual Frigate placement - TRAINING_MODE=face # STRATEGY: auto = objective diversity (recommended), standard = 30 imgs, broad = 100 imgs - STRATEGY=auto # - LIMIT=50 # Custom image count; overrides STRATEGY preset # - OBJECT_CLASS=dog # Object label for object mode (e.g. dog, cat, car) # ── People Filtering ────────────────────────────────────────────────── # - ONLY_PEOPLE=John,Jane # Comma-separated; process only these people # - SKIP_PEOPLE=Unknown # Comma-separated; skip these people # - MIN_FACE_COUNT=5 # Skip people with fewer than N assets in Immich # - YEARS_FILTER=10 # Only include images from the last N years (default: 10) # ── Image Quality ───────────────────────────────────────────────────── # - MIN_FACE_WIDTH=50 # Minimum face width in pixels (default: 50) # - FACE_MARGIN=0.15 # Padding around face crop as fraction (default: 0.15) # - ENABLE_FACE_ALIGNMENT=true # Align face before cropping (default: true) # - USE_FULL_RESOLUTION=true # Use full-res images vs thumbnails (default: true) # - MIN_CONFIDENCE=0.7 # Minimum face detection confidence (default: 0.7) # - BLUR_THRESHOLD=100.0 # Laplacian blur threshold; lower = accept more blur (default: 100.0) # - MAX_AUTO_IMAGES=80 # Hard cap on auto-diversity selection (default: 80) # ── Caching & Models ────────────────────────────────────────────────── # - FORCE_CPU=true # Disable GPU, fall back to CPU # - ENABLE_CACHE=false # Disable embedding cache (default: true) - CACHE_DIR=/app/.if_cache - HF_HOME=/models/huggingface - INSIGHTFACE_HOME=/models/.insightface # ── Tracker overrides (one-shot, remove after use) ──────────────────── # - DRY_RUN=true # Preview selection without downloading/uploading # - RETRY_REJECTED=true # Re-attempt previously rejected images # - RESET_PERSON=John # Clear uploaded+rejected history for one person # ── Scheduling ──────────────────────────────────────────────────────── # CRON_SCHEDULE controls container lifetime: # unset — run once on startup, then exit # empty string — stay alive, run nothing; trigger manually with: # docker exec -it winnow winnow # cron expression — run on startup, then on schedule # - CRON_SCHEDULE= # Manual mode (keep alive, no auto-run) # - CRON_SCHEDULE=0 3 * * 0 # Every Sunday at 3 AM # - CRON_SCHEDULE=0 3 1 * * # First of every month volumes: # Replace with absolute paths on your host, e.g. /opt/winnow/models - /path/to/winnow/models:/models - /path/to/winnow/cache:/app/.if_cache - /path/to/winnow/output:/app/frigate_train restart: unless-stopped deploy: resources: reservations: devices: - driver: nvidia count: all capabilities: [gpu]