diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..56471e91 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,55 @@ +# Python +__pycache__/ +*.py[cod] +*$py.class +*.so +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Virtual environments (uv best practice) +.venv/ +venv/ +env/ + +# Data +*.lancedb/ +data/ +docs/ + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Git +.git/ +.gitignore + +# Development +tests/ +.pytest_cache/ +.coverage +htmlcov/ + +# Examples +examples/ diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..7c689b6d --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,36 @@ +# syntax=docker/dockerfile:1 +FROM ghcr.io/astral-sh/uv:python3.13-bookworm-slim AS builder + +WORKDIR /app + +# Enable bytecode compilation for faster startup +ENV UV_COMPILE_BYTECODE=1 \ + UV_LINK_MODE=copy + +# Install dependencies into a venv +COPY pyproject.toml uv.lock ./ +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --frozen --no-install-project --extra voyageai --extra mxbai --extra a2a + +# Install the project itself +COPY . . +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync --frozen --no-editable --extra voyageai --extra mxbai --extra a2a + +# Final layer +FROM python:3.13-slim +WORKDIR /app +COPY --from=builder /app/.venv /app/.venv +COPY --from=builder /app /app + +# Set default data directory +RUN mkdir -p /data +ENV DEFAULT_DATA_DIR=/data + +ENV PATH="/app/.venv/bin:$PATH" + +# Expose ports for MCP and A2A +EXPOSE 8000 8001 + +# Run all services (monitoring, MCP, A2A) +CMD ["python", "-m", "haiku.rag.cli", "serve", "--monitor", "--mcp", "--mcp-port", "8001", "--a2a", "--a2a-host", "0.0.0.0", "--a2a-port", "8000", "--db", "/data/haiku.rag.lancedb"] diff --git a/docker/README.md b/docker/README.md new file mode 100644 index 00000000..bc621886 --- /dev/null +++ b/docker/README.md @@ -0,0 +1,27 @@ +# haiku.rag Docker Image + +Dockerfile for building haiku.rag with all extras (voyageai, mxbai, a2a). + +## Building + +```bash +docker build -f docker/Dockerfile -t haiku-rag . +``` + +## Running + +```bash +docker run -p 8000:8000 -p 8001:8001 \ + -v $(pwd)/data:/data \ + -e EMBEDDINGS_PROVIDER=ollama \ + -e EMBEDDINGS_MODEL=nomic-embed-text \ + -e QA_PROVIDER=ollama \ + -e QA_MODEL=qwen3\ + haiku-rag +``` + +Note: The environment variables above override the defaults. See [Configuration docs](https://ggozad.github.io/haiku.rag/configuration/) for all options. + +## Docker Compose + +See `examples/docker/` for a complete setup example. diff --git a/examples/README.md b/examples/README.md index 2e00c386..e3e3d7f0 100644 --- a/examples/README.md +++ b/examples/README.md @@ -2,6 +2,17 @@ This directory contains example scripts demonstrating various features of haiku.rag. +## Docker Example + +**Directory:** `docker/` + +Complete Docker setup for running haiku.rag with all services: +- File monitoring for automatic document indexing +- MCP server for AI assistant integration +- A2A agent for conversational interactions + +See `docker/README.md` for setup instructions. + ## A2A Security Examples **Directory:** `a2a-security/` diff --git a/examples/docker/.env.example b/examples/docker/.env.example new file mode 100644 index 00000000..00bddaae --- /dev/null +++ b/examples/docker/.env.example @@ -0,0 +1,16 @@ +# Database directory +DEFAULT_DATA_DIR=/data + +# File monitoring +MONITOR_DIRECTORIES=/docs + +# Default: Ollama on host +EMBEDDINGS_PROVIDER=ollama +EMBEDDINGS_MODEL=nomic-embed-text +QA_PROVIDER=ollama +QA_MODEL=qwen3 +OLLAMA_BASE_URL=http://host.docker.internal:11434 + +# For other providers, see: https://ggozad.github.io/haiku.rag/configuration/ + +ENV=production diff --git a/examples/docker/.gitignore b/examples/docker/.gitignore new file mode 100644 index 00000000..11476b40 --- /dev/null +++ b/examples/docker/.gitignore @@ -0,0 +1,8 @@ +# Data directory +data/ + +# Documents directory +docs/ + +# Environment file with secrets +.env diff --git a/examples/docker/README.md b/examples/docker/README.md new file mode 100644 index 00000000..d2dded0d --- /dev/null +++ b/examples/docker/README.md @@ -0,0 +1,47 @@ +# haiku.rag Docker Compose Example + +Run haiku.rag with file monitoring, MCP server, and A2A agent. + +## Quick Start + +```bash +mkdir -p data docs +cp .env.example .env # Edit if needed +docker compose up -d +``` + +Place documents in `docs/` for automatic indexing. + +## Usage + +```bash +# List documents +docker compose exec haiku-rag haiku-rag list + +# Search +docker compose exec haiku-rag haiku-rag search "your query" + +# Ask questions +docker compose exec haiku-rag haiku-rag ask "What is haiku.rag?" + +# A2A interactive client +docker compose exec haiku-rag haiku-rag a2aclient --url http://localhost:8000 +``` + +## Ports + +- `8000` - A2A agent +- `8001` - MCP server + +## Configuration + +Edit `.env` or `docker-compose.yml` to configure providers. See the [Configuration documentation](https://ggozad.github.io/haiku.rag/configuration/) for all options. + +Default setup uses Ollama on the host (`host.docker.internal:11434`). + +## Documentation + +- [Configuration](https://ggozad.github.io/haiku.rag/configuration/) +- [CLI Commands](https://ggozad.github.io/haiku.rag/cli/) +- [MCP Server](https://ggozad.github.io/haiku.rag/mcp/) +- [A2A Agent](https://ggozad.github.io/haiku.rag/a2a/) diff --git a/examples/docker/docker-compose.yml b/examples/docker/docker-compose.yml new file mode 100644 index 00000000..c4840f9c --- /dev/null +++ b/examples/docker/docker-compose.yml @@ -0,0 +1,60 @@ +services: + haiku-rag: + build: + context: ../.. + dockerfile: docker/Dockerfile + container_name: haiku-rag + ports: + - "8000:8000" # A2A server + - "8001:8001" # MCP server + volumes: + - ./data:/data # Persist database + - ./docs:/docs # Mount documents directory for monitoring + environment: + # Database directory + - DEFAULT_DATA_DIR=/data + + # File monitoring + - MONITOR_DIRECTORIES=/docs + + # Set the Ollama base url for Ollama defaults + - OLLAMA_BASE_URL=http://host.docker.internal:11434 + + # Embeddings provider (choose one) + # For OpenAI: + # - EMBEDDINGS_PROVIDER=openai + # - EMBEDDINGS_MODEL=text-embedding-3-small + # - OPENAI_API_KEY=your-key-here + + # For VoyageAI: + # - EMBEDDINGS_PROVIDER=voyageai + # - EMBEDDINGS_MODEL=voyage-3 + # - VOYAGE_API_KEY=your-key-here + + # QA provider (uses Pydantic AI) + # - QA_PROVIDER=ollama + + # For OpenAI: + # - QA_PROVIDER=openai + # - QA_MODEL=gpt-4o-mini + # - OPENAI_API_KEY=your-key-here + + # Reranking (optional) + # - RERANKING_PROVIDER=mxbai + # - RERANKING_MODEL=mixedbread-ai/mxbai-rerank-large-v1 + # - RERANKING_BASE_URL=http://host.docker.internal:11434 + + # Research agent (optional, defaults to QA provider/model) + # - RESEARCH_PROVIDER=openai + # - RESEARCH_MODEL=gpt-4o + + # Environment + - ENV=production + + restart: unless-stopped + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:8000/health"] + interval: 30s + timeout: 10s + retries: 3 + start_period: 40s diff --git a/pyproject.toml b/pyproject.toml index f04b8c82..8c61b7b7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build] -exclude = ["/docs", "/examples", "/tests", "/.github"] +exclude = ["/docs", "/examples", "/tests", "/docker", "/.github"] [tool.hatch.build.targets.wheel] packages = ["src/haiku"]