Ctrl K
ComunidadGuías…

docker-compose.quickstart.yml

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

Archivo original ↗Preguntar a KiBot
# =========================================================================
# Maestro — zero-configuration local trial.
#
#   docker compose -f docker-compose.quickstart.yml up -d
#   open http://localhost:8080
#
# Runs the published GHCR images, so nothing is built locally. Everything is
# published on 127.0.0.1 only. If something already owns port 8080, pick
# another one — MAESTRO_PORT=8090 docker compose -f ... up -d — it is applied
# to the proxy, the site address, and the link-building SITE_URL together.
#
# NOT A DEPLOYMENT. The credentials below are fixed, public, and identical on
# every machine that runs this file. They are safe here for exactly two
# reasons: nothing is reachable from outside the loopback interface, and
# ENVIRONMENT stays `development` — the backend refuses to boot in production
# with secrets this weak. To run Maestro for real, use
# docker-compose.prod.yml plus your own .env.prod (see docs/DEPLOYMENT.md).
#
# Chat runs on whichever provider key you add under Settings > API Keys;
# Google Gemini has a genuine free tier (no card). Embeddings run locally in
# the bundled Ollama service, so RAG needs no key. To run chat locally too:
#
#   docker compose -f docker-compose.quickstart.yml exec ollama ollama pull qwen3.5:9b
#
# and restart the backend — OLLAMA_CHAT_ENABLED is already true.
#
# The image tag is pinned to a release rather than `latest` or `main`, so a
# clone of any tag runs the code that tag actually shipped. It must be bumped
# in the same commit as the release, or the trial silently runs older code than
# the README describes. MAESTRO_TAG=main overrides it to the newest build.
#
# Requires Compose v2.17+ for `service_completed_successfully`.
# =========================================================================
name: maestro-quickstart

x-trial-logging: &trial-logging
  driver: json-file
  options:
    max-size: "10m"
    max-file: "3"

services:
  postgres:
    image: postgres:16-alpine
    restart: unless-stopped
    logging: *trial-logging
    environment:
      POSTGRES_USER: maestro
      POSTGRES_PASSWORD: maestro
      POSTGRES_DB: maestro
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U maestro -d maestro"]
      interval: 10s
      timeout: 5s
      retries: 5

  mongo:
    image: mongo:7
    restart: unless-stopped
    logging: *trial-logging
    environment:
      MONGO_INITDB_ROOT_USERNAME: maestro
      MONGO_INITDB_ROOT_PASSWORD: maestro
    volumes:
      - mongodata:/data/db
    healthcheck:
      test:
        - CMD
        - mongosh
        - --quiet
        - -u
        - maestro
        - -p
        - maestro
        - --authenticationDatabase
        - admin
        - --eval
        - db.adminCommand('ping').ok
      interval: 10s
      timeout: 5s
      retries: 5

  qdrant:
    image: qdrant/qdrant:v1.18.2
    restart: unless-stopped
    logging: *trial-logging
    volumes:
      - qdrantdata:/qdrant/storage
    # No healthcheck: the image is distroless, so no in-container probe can run.

  redis:
    image: redis:7-alpine
    restart: unless-stopped
    logging: *trial-logging
    command:
      - redis-server
      - --maxmemory
      - 128mb
      - --maxmemory-policy
      - allkeys-lru
      - --save
      - ""
      - --appendonly
      - "no"
    healthcheck:
      test: ["CMD-SHELL", "redis-cli ping | grep -q PONG"]
      interval: 10s
      timeout: 5s
      retries: 5

  # Embeddings for RAG. A chat model is not pulled here — see the header for
  # the one command that adds it.
  ollama:
    image: ollama/ollama:latest
    restart: unless-stopped
    logging: *trial-logging
    volumes:
      - ollamadata:/root/.ollama
    healthcheck:
      test: ["CMD", "/bin/ollama", "list"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 20s

  # Idempotent: exits immediately once the model is in the volume.
  ollama-pull:
    image: ollama/ollama:latest
    restart: "no"
    logging: *trial-logging
    entrypoint: ["/bin/ollama"]
    command: ["pull", "nomic-embed-text"]
    environment:
      OLLAMA_HOST: http://ollama:11434
    depends_on:
      ollama:
        condition: service_healthy

  # Runs `alembic upgrade head` and exits; the API waits for it to succeed.
  migrate:
    image: ghcr.io/yigtwxx/maestro-backend:${MAESTRO_TAG:-0.1.2}
    restart: "no"
    logging: *trial-logging
    command: ["alembic", "upgrade", "head"]
    environment: &backend-env
      ENVIRONMENT: development
      POSTGRES_URL: postgresql+asyncpg://maestro:maestro@postgres:5432/maestro
      MONGODB_URL: mongodb://maestro:maestro@mongo:27017/?authSource=admin
      MONGODB_DB_NAME: maestro
      QDRANT_URL: http://qdrant:6333
      REDIS_URL: redis://redis:6379/0
      # Local-trial values only — see the header. Both are deliberately
      # readable rather than random: the master key loader accepts base64, hex
      # or raw UTF-8 as long as it decodes to 32 bytes, and a plain 32-character
      # string cannot be mistaken for a real credential by a human or by a
      # secret scanner. Count the characters before changing this line.
      JWT_SECRET: quickstart-insecure-jwt-secret-not-for-any-real-deployment
      API_KEY_MASTER_KEY: quickstart-insecure-master-key00
      # Console provider: verification links are printed to the backend log.
      # Verification is off here so the trial needs no mail round-trip at all.
      EMAIL_PROVIDER: console
      EMAIL_VERIFICATION_REQUIRED: "false"
      SITE_URL: http://localhost:${MAESTRO_PORT:-8080}
      FREE_MODEL_ENDPOINT: http://ollama:11434/v1
      EMBEDDING_ENDPOINT: http://ollama:11434/v1
      OLLAMA_CHAT_ENABLED: "true"
      # The Docker socket is not mounted here, so the sandbox stays off.
      CODE_EXECUTION_ENABLED: "false"
      TRUST_PROXY_HEADERS: "true"
    depends_on:
      postgres:
        condition: service_healthy

  backend:
    image: ghcr.io/yigtwxx/maestro-backend:${MAESTRO_TAG:-0.1.2}
    restart: unless-stopped
    logging: *trial-logging
    environment: *backend-env
    depends_on:
      postgres:
        condition: service_healthy
      mongo:
        condition: service_healthy
      qdrant:
        condition: service_started
      redis:
        condition: service_healthy
      migrate:
        condition: service_completed_successfully
      ollama-pull:
        condition: service_completed_successfully

  frontend:
    image: ghcr.io/yigtwxx/maestro-frontend:${MAESTRO_TAG:-0.1.2}
    restart: unless-stopped
    logging: *trial-logging
    environment:
      INTERNAL_API_ORIGIN: http://backend:8000
      SITE_URL: http://localhost:${MAESTRO_PORT:-8080}
    depends_on:
      - backend

  # Single origin, so the browser needs no baked-in API URL and there is no
  # CORS. The shared Caddyfile skips certificate provisioning when DOMAIN
  # carries an explicit http:// scheme.
  caddy:
    image: caddy:2-alpine
    restart: unless-stopped
    logging: *trial-logging
    ports:
      - "127.0.0.1:${MAESTRO_PORT:-8080}:${MAESTRO_PORT:-8080}"
    environment:
      DOMAIN: http://localhost:${MAESTRO_PORT:-8080}
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile:ro
      - caddydata:/data
      - caddyconfig:/config
    depends_on:
      - backend
      - frontend

volumes:
  pgdata:
  mongodata:
  qdrantdata:
  ollamadata:
  caddydata:
  caddyconfig: