diff --git a/Dockerfile b/Dockerfile index 75ba235..5275f48 100644 --- a/Dockerfile +++ b/Dockerfile @@ -46,9 +46,13 @@ ENV PYTHONUNBUFFERED=1 \ MCP_TRANSPORT=streamable-http \ MCP_HOST=0.0.0.0 \ MCP_PORT=8000 \ - HYBRID_SEARCH=true - # RERANK_URL set at deploy time, e.g. http://llama-rerank:8080 - # OLLAMA_URL set at deploy time, comma-separated list + HYBRID_SEARCH=true \ + OLLAMA_URL=http://ollama:11434 \ + RERANK_URL=http://llama-rerank:8080 + # Defaults above assume the MCP container shares a Docker network + # with services named `ollama` and `llama-rerank`. Override either + # in the compose `environment:` block if your stack uses different + # service names or if you want to point at off-stack hosts. EXPOSE 8000 diff --git a/deploy/drawbar-compose-snippet.md b/deploy/drawbar-compose-snippet.md index ace4f9c..63ac955 100644 --- a/deploy/drawbar-compose-snippet.md +++ b/deploy/drawbar-compose-snippet.md @@ -1,8 +1,8 @@ # Drawbar deploy — `crop-chem-docs` MCP server snippet Drop this into Drawbar's `docker-compose.yml`. Targets the existing -trashpanda infra: Ollama pool on the LAN, `llama-rerank` container -on Tesla P4, Cloudflare Tunnel out front. +trashpanda stack: shared Docker network with `ollama` + `llama-rerank` +service containers, Cloudflare Tunnel out front. ## Pre-reqs (one-time on the deploy host) @@ -10,53 +10,48 @@ on Tesla P4, Cloudflare Tunnel out front. ```bash docker login git.jpaul.io -u justin # PAT for password ``` -2. **Ollama embed pool** reachable from this host (already up): - - `192.168.0.2:11434`, `192.168.0.2:11435` (Gitea-host GPUs) - - `192.168.0.125:11434` (Windows GPU) -3. **Reranker** reachable (already up on trashpanda): - - `http://10.10.1.65:8082` +2. **`ollama` and `llama-rerank` services** are already running in + the same compose stack on the same Docker network. The MCP + container resolves them by service name via Docker's embedded + DNS — no IPs to maintain. ## Compose service ```yaml services: crop-chem-docs: - image: git.jpaul.io/justin/crop-chem-docs:latest - # Or pin to an immutable tag for prod: - # image: git.jpaul.io/justin/crop-chem-docs:corpus-2026.05.24 + image: git.jpaul.io/justin/crop-chem-docs:corpus-2026.05.24 + # :latest for dev / Watchtower auto-pull container_name: crop-chem-docs restart: unless-stopped ports: - "8001:8000" # MCP server (streamable-http). Adjust host port. - environment: - # Embedder pool. Round-robined for parallel search. - OLLAMA_URL: "http://192.168.0.2:11434,http://192.168.0.2:11435,http://192.168.0.125:11434,http://10.10.1.65:11434" - # Reranker on trashpanda's Tesla P4. - RERANK_URL: "http://10.10.1.65:8082" - # Production retrieval: BM25 + dense fused, then reranked. - HYBRID_SEARCH: "true" - # Override docs URL shown to the LLM if needed (default is EPA PPLS portal). - # PRODUCT_DOCS_URL: "https://..." + # No environment block needed — the image's defaults handle it: + # OLLAMA_URL=http://ollama:11434 + # RERANK_URL=http://llama-rerank:8080 + # HYBRID_SEARCH=true + # PRODUCT_NAME=crop_chem + # Override here only if your services have different names. + networks: + - default # or whichever shared network ollama/llama-rerank are on labels: - # Watchtower auto-pulls :latest on update. com.centurylinklabs.watchtower.enable: "true" +``` - # Optional: if you want Watchtower to drive auto-updates of this - # container too, you already run watchtower elsewhere — just make - # sure this container has the label above set true. +If your stack uses non-default service names: + +```yaml + environment: + OLLAMA_URL: "http://:11434" + RERANK_URL: "http://:8080" ``` ## Test from the host ```bash -# Tool inventory (uses MCP's HTTP transport — adjust if you have a -# different MCP client probe handy): -curl -s http://localhost:8001/sse # or whichever endpoint your - # client expects from streamable-http - -# Or exec into the container and run the stdio transport: -docker exec -it crop-chem-docs \ - python -m docs_mcp.server --transport stdio < /dev/null +# Verify counts + indexes from inside the container: +docker exec crop-chem-docs python -c \ + "from docs_mcp.server import corpus_status; print(corpus_status())" ``` ## What the container exposes @@ -67,32 +62,22 @@ docker exec -it crop-chem-docs \ | `get_page` | Full label markdown + metadata by `(source, source_key)` | | `list_versions` | Discover sources, product classes, signal words, registrants | | `corpus_status` | Counts + freshness; useful for health probes | -| `crop_chem_api_lessons` | Curated agronomy/label-handling knowledge — call before recommending | +| `crop_chem_api_lessons` | Curated agronomy / label-handling knowledge — call before recommending | -## Versioning - -Tags published by the Gitea Actions workflows: +## Tag scheme | Tag | When | Use for | |---|---|---| | `:latest` | Every monthly refresh + every code push | Dev / Watchtower auto-pull | | `:` | Every build | Rollback pin | -| `:corpus-YYYY.MM.DD` | Every build | Pin to a specific corpus snapshot in prod | - -The `:corpus-YYYY.MM.DD` tag is the right one for production — -guarantees the running container has a known, frozen corpus that -matches the labels you've validated against. +| `:corpus-YYYY.MM.DD` | Every build | **Production pin** (frozen corpus version) | ## Updating the corpus -Two paths: - -1. **Wait for the monthly cron** — 1st @ 06:00 UTC, full re-scrape - of Bayer + EPA PPLS, then reindex, then image push. Watchtower - pulls the new `:latest` automatically. -2. **Trigger manually** in Gitea Actions UI → `Monthly corpus - refresh` → `Run workflow`. Optional `sources` input for - single-source refresh (e.g., `bayer` only). +- **Monthly cron** — 1st @ 06:00 UTC, full re-scrape of Bayer + EPA PPLS, + reindex, image push. Watchtower pulls the new `:latest` automatically. +- **Manual** — Gitea Actions UI → `Monthly corpus refresh` → `Run workflow`. + Optional `sources` input for single-source refresh (e.g., `bayer` only). ## Switching corpus scope