Ctrl K
ComunidadGuías…

docker-compose.yml

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

Archivo original ↗Preguntar a KiBot
name: paperlab

x-backend: &backend
  build: ./backend
  # Optional: every setting has a default in app/config.py (Docker Compose 2.24 or later).
  env_file:
    - path: .env
      required: false
  volumes:
    - ./backend:/src
    - pdfs:/data/pdfs
    - models:/models
  depends_on:
    db:
      condition: service_healthy
    redis:
      condition: service_healthy

# What the main and the ingest worker share; only the main worker compiles, so only it gets TECTONIC_USER.
x-worker-env: &worker-env
  DISCOVERY_PROVIDER: ${DISCOVERY_PROVIDER:-live}
  # Search sources behind a model connection embed here, so the E2E stack's fake providers must reach the worker
  # too: a real source would record real names while the API reads `fake:` ones.
  LLM_PROVIDER: ${LLM_PROVIDER:-ollama}
  # The built-in search model's folder. E2E's no-search-model run points it at an empty one (README).
  MODELS_DIR: ${MODELS_DIR:-/models}
  # Threads the search model may use; unset it takes min(4, cores). Uncomment to change that.
  # EMBED_THREADS: 4
  PAPERLAB_STACK: ${COMPOSE_PROJECT_NAME}
  DEV_RELOAD: ${DEV_RELOAD:-} # see the api

services:
  db:
    image: pgvector/pgvector:pg16
    environment:
      POSTGRES_USER: paperlab
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-paperlab}
      POSTGRES_DB: paperlab
    ports: ["127.0.0.1:${DB_PORT:-5433}:5432"]
    volumes: [pgdata:/var/lib/postgresql/data]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U paperlab"]
      interval: 2s
      retries: 30

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 2s
      retries: 30

  api:
    <<: *backend
    # Shell > .env > default. E2E runs on its own stack: scripts/e2e-stack.sh (README).
    environment:
      LLM_PROVIDER: ${LLM_PROVIDER:-ollama}
      DISCOVERY_PROVIDER: ${DISCOVERY_PROVIDER:-live}
      # The compose project (`paperlab`, or `paperlab-e2e` from scripts/e2e-stack.sh). Fake providers refuse to start
      # unless it ends in -e2e (D273).
      PAPERLAB_STACK: ${COMPOSE_PROJECT_NAME}
      # The folder `docker compose up` ran in, for the Connect Claude page (Compose uses its own working directory
      # when the shell exports no PWD).
      PAPERLAB_DIR: ${PWD:-}
      # The built-in search model's folder. E2E's no-search-model run points it at an empty one (README).
      MODELS_DIR: ${MODELS_DIR:-/models}
      # Any non-empty DEV_RELOAD (e.g. DEV_RELOAD=1) restarts the api and workers on every saved change under backend/.
      # Off by default: when your own library runs from this folder, a save would cancel its running jobs. scripts/e2e-stack.sh turns it on.
      DEV_RELOAD: ${DEV_RELOAD:-}
    # Killed for memory (a test stack beside it did that twice on 2026-10-15) or crashed, it comes back; stopped by hand,
    # it stays stopped. on-failure, not always: nothing starts with Docker itself. The workers set it too.
    restart: on-failure
    command: sh -c 'alembic upgrade head && exec uvicorn app.main:app --host 0.0.0.0 --port 8000 $${DEV_RELOAD:+--reload}'
    ports: ["127.0.0.1:${API_PORT:-8000}:8000"]

  worker: &worker
    <<: *backend
    restart: on-failure # see the api
    # The References fetch runs here, so the E2E stack's fake discovery must reach the worker too.
    environment:
      <<: *worker-env
      TECTONIC_USER: tex # manuscripts compile as this unprivileged account (the ingest worker never compiles)
    # With DEV_RELOAD, watchfiles, not `arq --watch`: that restarts the worker in-process and never re-imports changed
    # code.
    command: >-
      sh -c 'if [ -n "$$DEV_RELOAD" ]; then exec watchfiles --filter python "arq app.workers.settings.WorkerSettings" app;
      else exec arq app.workers.settings.WorkerSettings; fi'

  ingest-worker:
    <<: *worker
    environment: *worker-env
    # A paper's ingest and re-embed, one paper at a time: ten at once ran the worker out of memory.
    command: >-
      sh -c 'if [ -n "$$DEV_RELOAD" ]; then exec watchfiles --filter python "arq app.workers.settings.IngestWorkerSettings" app;
      else exec arq app.workers.settings.IngestWorkerSettings; fi'

  frontend:
    build: ./frontend
    environment:
      API_URL: http://api:8000
    ports: ["127.0.0.1:${FRONTEND_PORT:-5180}:5173"]
    volumes:
      - ./frontend:/app
      - /app/node_modules
    depends_on: [api]

volumes:
  pgdata:
  pdfs:
  models: