Ctrl K
ComunidadGuías…

docker-compose.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# ClippyMe Docker Compose
#
# CPU / Apple Silicon / ARM (default):
#   docker compose up --build
#
# NVIDIA GPU:
#   docker compose -f docker-compose.yml -f docker-compose.gpu.yml up --build

name: clippyme

networks:
  clippyme-net:
    driver: bridge

services:
  backend:
    build:
      context: .
      args:
        GPU_RUNTIME: ${GPU_RUNTIME:-cpu}
        # Set ENABLE_WHISPER_DIARIZE=1 in your shell/.env to bake
        # pyannote.audio into the image and enable speaker diarization on
        # the Faster-Whisper fallback path. Adds ~500 MB to the image.
        ENABLE_WHISPER_DIARIZE: ${ENABLE_WHISPER_DIARIZE:-0}
    container_name: clippyme-backend
    image: clippyme-backend
    ports:
      # Bound to loopback: security.py treats every RFC1918 peer as a trusted
      # client for the config/state endpoints (key overwrite, cookie download,
      # job deletion), so publishing on 0.0.0.0 hands that trust to the whole
      # LAN. Override CLIPPYME_BIND (e.g. CLIPPYME_BIND=0.0.0.0) ONLY on a
      # network where every device is trusted.
      - "${CLIPPYME_BIND:-127.0.0.1}:8000:8000"
    dns:
      - 8.8.8.8
      - 8.8.4.4
    environment:
      # HuggingFace token — required for pyannote diarization + Whisper
      # model downloads without rate limits. Both names are accepted.
      - HF_TOKEN=${HF_TOKEN:-}
      - HUGGINGFACE_TOKEN=${HUGGINGFACE_TOKEN:-${HF_TOKEN:-}}
      # ASR provider + credentials. TRANSCRIPTION_PROVIDER=deepgram|elevenlabs|whisper.
      - TRANSCRIPTION_PROVIDER=${TRANSCRIPTION_PROVIDER:-deepgram}
      - DEEPGRAM_API_KEY=${DEEPGRAM_API_KEY:-}
      - DEEPGRAM_MODEL=${DEEPGRAM_MODEL:-nova-3}
      # Default 'multi' enables Nova-3 native EN+IT code-switching.
      # Users can override per-job from the Create tab dropdown.
      - DEEPGRAM_LANGUAGE=${DEEPGRAM_LANGUAGE:-multi}
      - DEEPGRAM_DIARIZE=${DEEPGRAM_DIARIZE:-true}
      # ElevenLabs Scribe (3rd STT provider). scribe_v2 supports NO_VERBATIM
      # filler-strip. AUDIO_ISOLATION=1 adds an opt-in pre-ASR noise/music
      # removal pass (provider-agnostic; needs the ElevenLabs key).
      - ELEVENLABS_API_KEY=${ELEVENLABS_API_KEY:-}
      - ELEVENLABS_MODEL=${ELEVENLABS_MODEL:-scribe_v1}
      - ELEVENLABS_LANGUAGE=${ELEVENLABS_LANGUAGE:-multi}
      - ELEVENLABS_DIARIZE=${ELEVENLABS_DIARIZE:-true}
      - ELEVENLABS_NO_VERBATIM=${ELEVENLABS_NO_VERBATIM:-false}
      - ELEVENLABS_AUDIO_ISOLATION=${ELEVENLABS_AUDIO_ISOLATION:-false}
      # Whisper fallback diarization. Requires ENABLE_WHISPER_DIARIZE=1
      # at build time AND HF_TOKEN set at runtime.
      - WHISPER_DIARIZE=${WHISPER_DIARIZE:-true}
      # Gemini key is normally passed per-request via the X-Gemini-Key
      # header, but can also be set here for CLI runs that shell into the
      # container directly.
      - GEMINI_API_KEY=${GEMINI_API_KEY:-}
      - GEMINI_MODEL=${GEMINI_MODEL:-gemini-3.5-flash}
      # yt-dlp hardening. NOCHECKCERT=1 disables SSL verification only in
      # trusted sandboxes; THROTTLED_RATE is the bytes/sec floor below
      # which yt-dlp re-fetches a slow segment (default 102400 = 100 KB/s).
      - YTDLP_NOCHECKCERT=${YTDLP_NOCHECKCERT:-}
      - YTDLP_THROTTLED_RATE=${YTDLP_THROTTLED_RATE:-}
      # Auto-purge of output/ and uploads/ folders. 0 = disabled
      # (recommended — the History tab's Delete button is the single
      # source of truth). Default fallback in app.py is 30 days.
      - JOB_RETENTION_SECONDS=${JOB_RETENTION_SECONDS:-0}
      # Reframe camera tuning (all optional; defaults preserve current feel).
      # REFRAME_SMOOTHER=euro switches the active-speaker camera to the 1€
      # adaptive filter; leave blank for the proven two-speed EMA. The LOST_*
      # knobs control lost-subject drift-to-center (always on). EURO_* tune the
      # 1€ filter when enabled. See docs/architecture/reframe.md.
      - REFRAME_SMOOTHER=${REFRAME_SMOOTHER:-}
      - REFRAME_LOST_HOLD=${REFRAME_LOST_HOLD:-90}
      - REFRAME_LOST_DRIFT=${REFRAME_LOST_DRIFT:-0.05}
      - REFRAME_EURO_MINCUTOFF=${REFRAME_EURO_MINCUTOFF:-0.014}
      - REFRAME_EURO_BETA=${REFRAME_EURO_BETA:-0.0008}
      # Comfort mode (anti-nausea, DEFAULT ON): biases the camera toward a locked
      # crop + fixed per-scene zoom (the research-backed fix for seasickness from
      # continuous tracking). Costs a second decode pass. Set REFRAME_COMFORT=0
      # to revert to the original single-pass streaming tracker. STATIONARY_THRESH
      # / ZOOM_LOCK override the comfort defaults (0.30 / on) when set explicitly.
      - REFRAME_COMFORT=${REFRAME_COMFORT:-1}
      - REFRAME_STATIONARY_THRESH=${REFRAME_STATIONARY_THRESH:-}
      - REFRAME_ZOOM_LOCK=${REFRAME_ZOOM_LOCK:-}
      - REFRAME_SNAP_CENTER=${REFRAME_SNAP_CENTER:-0.10}
      # AUTO static-framing policy (DEFAULT ON): collapse each scene to ONE fixed
      # crop so the camera is a locked tripod within every shot — zero pan, zero
      # mid-shot zoom. TRACK locks on the static face; a single subject that
      # MOVES more than MOTION_WIDE_THRESH (fraction of frame) is demoted to WIDE
      # (locked, zoomed-out) instead of being chased; 2+ faces also → WIDE. Set
      # REFRAME_STATIC_AUTO=0 to fall back to the per-frame eased smoother.
      - REFRAME_STATIC_AUTO=${REFRAME_STATIC_AUTO:-}
      - REFRAME_MOTION_WIDE_THRESH=${REFRAME_MOTION_WIDE_THRESH:-0.12}
      # Opt-in: content-aware crop for faceless (GENERAL) scenes instead of
      # letterboxing (Sobel saliency). Default off = byte-identical letterbox.
      - REFRAME_SALIENT_GENERAL=${REFRAME_SALIENT_GENERAL:-}
      # Opt-in: in faceless (GENERAL) scenes, follow a weighted-object centroid
      # (product/dog/car) by reusing the existing YOLO pass — no 2nd network.
      # `1` = curated COCO defaults; `dog:3,car:2,bottle:1.5` = custom weights.
      # Takes precedence over SALIENT_GENERAL; default off = byte-identical.
      - REFRAME_OBJECT_WEIGHTS=${REFRAME_OBJECT_WEIGHTS:-}
      # FrameShift face-first `object` reframe mode weights (defaults mirror the
      # FrameShift GUI: face 1.0, person 0.8, default 0.5). Override per class,
      # e.g. `face:1,person:0.8,default:0.5,dog:3`. Empty = GUI defaults.
      - REFRAME_FRAMESHIFT_WEIGHTS=${REFRAME_FRAMESHIFT_WEIGHTS:-}
      # Encode quality (shared by every libx264 render/compose pass — reframe,
      # zoom, grade, subtitles, smart-cut, hook, logo). CRF 18 / preset medium is
      # near-visually-lossless so the stacked re-encodes don't compound into soft
      # output. Lower CRF = higher quality + bigger files (0-51); a faster preset
      # (e.g. `fast`/`veryfast`) trades a little quality/size for render speed.
      - CLIPPYME_X264_CRF=${CLIPPYME_X264_CRF:-18}
      - CLIPPYME_X264_PRESET=${CLIPPYME_X264_PRESET:-medium}
      # Transcription: strip to audio-only (FLAC) before sending to the provider.
      # DEFAULT ON; set to false to upload/decode the full video.
      - CLIPPYME_TRANSCRIBE_AUDIO_ONLY=${CLIPPYME_TRANSCRIBE_AUDIO_ONLY:-true}
      # Optional shared-secret auth for /api. Unset (default) = no auth beyond
      # the private-network trust model. Set together with CLIPPYME_BIND=0.0.0.0
      # for a deliberate LAN deployment: every API request must then carry
      # X-API-Token (the dashboard has a Settings field for it).
      - CLIPPYME_API_TOKEN=${CLIPPYME_API_TOKEN:-}
    volumes:
      - .:/app
      - /app/__pycache__
      - ./data:/app/data
    networks:
      - clippyme-net
    restart: unless-stopped

  frontend:
    build: ./dashboard
    container_name: clippyme-frontend
    image: clippyme-frontend
    ports:
      # Loopback too: the Vite dev proxy forwards /api to the backend from
      # INSIDE the docker network, where the frontend container is itself a
      # trusted private peer — so a LAN-exposed dashboard would reopen the
      # exact hole the backend loopback binding closes. Same CLIPPYME_BIND
      # override applies.
      - "${CLIPPYME_BIND:-127.0.0.1}:5175:5175"
    volumes:
      - ./dashboard:/app
      - /app/node_modules
    networks:
      - clippyme-net
    restart: unless-stopped
    depends_on:
      - backend