Ctrl K
ComunidadGuías…

docker-compose.yml

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

Archivo original ↗Preguntar a KiBot
# =========================================================================
# Maestro Platform — local infrastructure
# Brings up Postgres, MongoDB, Qdrant and Redis for development.
# The FastAPI backend and Next.js frontend run on the host (see README).
# Ollama also runs on the host (`ollama serve`) so it can use the GPU.
#
# Redis is optional locally: leave REDIS_URL unset and the rate limiter keeps
# its buckets in process memory, which is correct for a single dev worker.
#
# Every service carries a `mem_limit`, mirroring docker-compose.prod.yml. Without
# one, each container sizes its caches from the whole WSL2 VM; the four of them
# together starved the Next.js dev server on the host and froze the machine.
# The VM itself is capped separately in %USERPROFILE%\.wslconfig.
# =========================================================================
services:
  postgres:
    image: postgres:16-alpine
    container_name: maestro-postgres
    restart: unless-stopped
    mem_limit: 512m
    environment:
      POSTGRES_USER: maestro
      POSTGRES_PASSWORD: maestro
      POSTGRES_DB: maestro
    ports:
      # Host port 5433: a native PostgreSQL service on Windows already owns 5432.
      - "5433:5432"
    volumes:
      - ./.data/postgres:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U maestro -d maestro"]
      interval: 10s
      timeout: 5s
      retries: 5

  mongo:
    image: mongo:7
    container_name: maestro-mongo
    restart: unless-stopped
    mem_limit: 1g
    # WiredTiger sizes its cache from *visible* RAM, which inside WSL2 is the
    # whole VM — it ignores the cgroup limit and would get OOM-killed instead.
    command: ["mongod", "--wiredTigerCacheSizeGB", "0.5"]
    ports:
      # Host port 27018, for the same reason Postgres uses 5433: a native
      # MongoDB service (Homebrew's mongodb-community, Windows' MongoDB
      # service) already owns 27017 on plenty of dev machines. It binds
      # 127.0.0.1 specifically while Docker's proxy binds the wildcard, and a
      # loopback-specific bind wins — so `localhost:27017` silently reaches the
      # *native* server, not this container. Those installs default to
      # authorization enabled, which surfaces as an unrelated-looking
      # "Command update requires authentication" from the seed script.
      - "27018:27017"
    volumes:
      # A named volume, unlike its bind-mounted siblings. WiredTiger cannot open
      # an *existing* data file over Docker Desktop's VirtioFS share on macOS:
      # `/data/db/WiredTiger.wt: handle-open: open` returns EPERM ("Operation not
      # permitted") and mongod turns that into a fatal assertion, so the
      # container crash-loops. A fresh dbpath initialises fine, which is why the
      # failure only appears on the *second* start, once the files exist — and
      # why it looks like a connection error from the seed script rather than a
      # storage one. Postgres, Qdrant and Redis keep their bind mounts; none of
      # them touches the file in the way that trips this. This also matches
      # docker-compose.prod.yml, which has always used a named `mongodata`.
      - mongodata:/data/db
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5

  qdrant:
    # Pinned to the same tag as production; `latest` silently changed the storage
    # format between runs and mmaps the segment store on start.
    image: qdrant/qdrant:v1.18.2
    container_name: maestro-qdrant
    restart: unless-stopped
    mem_limit: 1g
    ports:
      - "6333:6333" # REST
      - "6334:6334" # gRPC
    volumes:
      - ./.data/qdrant:/qdrant/storage
    # The image ships no curl/wget and its /bin/sh is dash, so CMD-SHELL cannot
    # probe anything — but bash *is* installed, and its /dev/tcp redirection
    # speaks enough HTTP to read Qdrant's own /readyz. That endpoint answers
    # without the API key, so the same probe works in docker-compose.prod.yml.
    healthcheck:
      test:
        - CMD
        - bash
        - -c
        - "exec 3<>/dev/tcp/127.0.0.1/6333 && printf 'GET /readyz HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n' >&3 && grep -q '200 OK' <&3"
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    container_name: maestro-redis
    restart: unless-stopped
    mem_limit: 256m
    # Rate-limit buckets expire in 60s, so eviction under pressure costs nothing.
    command: ["redis-server", "--maxmemory", "192mb", "--maxmemory-policy", "allkeys-lru"]
    ports:
      - "6379:6379"
    volumes:
      - ./.data/redis:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

# Only MongoDB needs one — see the comment on the mongo service. The bind-mounted
# services keep their data under ./.data, which is gitignored and safe to delete.
volumes:
  mongodata: