# Base deployment: the app with a persistent cache volume and no language model. # # cp .env.example .env # add MP_API_KEY (and OPENALEX_MAILTO) # docker compose -f docker/compose.yml up --build # docker compose -f docker/compose.yml run --rm app oxide-triage warm-cache # open http://localhost:8000 # # Everything the site admin edits lives in ./config (mounted read-only), .env, and the site # overrides file the admin panel writes to /data/site.yaml (OXIDE_TRIAGE_ADMIN=1 to enable editing). name: oxide-triage services: app: build: context: .. dockerfile: docker/Dockerfile image: oxide-triage:latest env_file: - ../.env environment: OXIDE_TRIAGE_CACHE: /data/cache.sqlite # LLM_PROVIDER defaults to `none`: the system is fully functional without a model. # The assistant is driven by a model with a provider: `LLM_PROVIDER=anthropic docker compose ...` with # ANTHROPIC_API_KEY in .env, or `LLM_PROVIDER=openai_compatible` with OPENAI_API_KEY (or # LLM_BASE_URL and LLM_MODEL for a vLLM/Ollama server the container can reach). This line # beats the env_file, so the variable must be set in the shell that runs compose. LLM_PROVIDER: ${LLM_PROVIDER:-none} # Admin panel editing and cache operations. No per-user login: leave it off on a shared network. OXIDE_TRIAGE_ADMIN: ${OXIDE_TRIAGE_ADMIN:-0} volumes: - cache:/data - ../config:/app/config:ro ports: - "${OXIDE_TRIAGE_PORT:-8000}:8000" restart: unless-stopped # MCP endpoint for Claude Desktop / Cowork / Cursor over the network (streamable HTTP). # Desktop apps on the same machine can instead launch `oxide-triage mcp` over stdio; see # docker/mcp-client-config.example.json. mcp: image: oxide-triage:latest command: ["oxide-triage", "mcp", "--transport", "http", "--host", "0.0.0.0", "--port", "8765"] env_file: - ../.env environment: OXIDE_TRIAGE_CACHE: /data/cache.sqlite OXIDE_TRIAGE_OFFLINE: ${OXIDE_TRIAGE_OFFLINE:-0} LLM_PROVIDER: none # the MCP client's own model is the front edge volumes: - cache:/data - ../config:/app/config:ro ports: - "127.0.0.1:${OXIDE_TRIAGE_MCP_PORT:-8765}:8765" # loopback; put a reverse proxy with auth in front for LAN use depends_on: - app restart: unless-stopped volumes: cache: