Ctrl K
ComunidadGuías…

docker-compose.yml

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

Archivo original ↗Preguntar a KiBot
# Dev stack: frontend (nginx) + backend (uvicorn --reload, source bind-mounted)
# + the hunter (the agent daemon). Postgres is NOT here — every service uses
# the existing LAN DB (DATABASE_URL in each .env, kept out of the images by
# .dockerignore). The Playwright MCP the agent drives is external too
# (PLAYWRIGHT_MCP_URL in agent/.env) and must run with --isolated: the daemon
# opens one browser context per job.
#
#   docker compose up --build                    # frontend http://localhost:8081, API http://localhost:8000
#   docker compose --profile vision up --build   # + the visual-authenticity sidecar (:8100) and its minio
#                                                #   (image bytes persist in the minio-data volume,
#                                                #    DINOv3 weights cache in vision-hf-cache)
#
# Editing backend/app/** hot-reloads inside the container. Changing
# requirements.txt (or frontend/agent code) needs a rebuild: docker compose up --build.

services:
  backend:
    build: ./backend
    env_file: backend/.env
    ports:
      - "8000:8000" # also lets `npm run dev` (Vite proxy) hit the containerized API
    # Dev overrides: hot-reload on the mounted source. A production deploy drops
    # both `command` and `volumes` and runs the image's baked-in CMD.
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload
    volumes:
      - ./backend/app:/app/app:ro
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/api/instance')"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 10s

  agent:
    build: ./agent
    # agent/.env is written for host runs (127.0.0.1); the .docker overlay,
    # loaded second, re-points the DB and Playwright MCP at container names.
    env_file:
      - agent/.env
      - agent/.env.docker
    restart: unless-stopped
    # The hunter runs as a daemon: it LISTENs for work and claims it as it
    # appears, so a UI-triggered hunt or "check prices" starts in seconds
    # rather than on the next tick. SIGTERM unwinds the pools and hands every
    # in-flight job back to the queue; the grace period is how long that gets
    # before the kill.
    #
    # The Playwright MCP this talks to (PLAYWRIGHT_MCP_URL in agent/.env.docker)
    # must run with --isolated: the daemon opens one browser context per job,
    # and a server on a persistent profile refuses the second one.
    command: python main.py --serve
    stop_grace_period: 30s

  frontend:
    build: ./frontend
    ports:
      - "8081:80" # 8080 is taken by VS Code on this machine
    depends_on:
      - backend

  # --- vision profile (opt-in): docker compose --profile vision up --build ------
  # The visual-authenticity sidecar and its object store. Optional by design:
  # with VISION_SIDECAR_URL unset in backend/agent the feature is off
  # and plain `docker compose up` is unchanged. LAN-INTERNAL, UNAUTHENTICATED —
  # publish these ports to trusted interfaces only.
  minio:
    image: minio/minio
    profiles: ["vision"]
    command: server /data --console-address ":9001"
    environment:
      # must match S3_ACCESS_KEY / S3_SECRET_KEY in vision/.env
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-snagr-minio}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-snagr-minio-secret}
    volumes:
      - minio-data:/data # image bytes persist here
    # ports:
    #   - "9001:9001" # minio web console — enable for debugging only
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"]
      interval: 30s
      timeout: 5s
      retries: 3

  vision:
    build: ./vision
    profiles: ["vision"]
    env_file: vision/.env
    environment:
      S3_ENDPOINT: http://minio:9000 # in-network address overrides vision/.env
    ports:
      - "8100:8100" # host-run agent / backend dev servers reach it here
    depends_on:
      - minio
    volumes:
      - vision-hf-cache:/home/vision/.cache/huggingface # weights survive restarts
    healthcheck:
      test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8100/health')"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 60s # first start may be downloading weights

volumes:
  minio-data:
  vision-hf-cache: