feat(dev): self-hosted LiteLLM proxy compose service#361
Conversation
CONTRIBUTING.md and AGENTS.md treat 'a LiteLLM gateway URL' as a prereq
without documenting where it comes from. New contributors trying the
docker-compose flow either reach for a hosted Berri instance (account +
key + cost) or skip the platform entirely.
Add an optional compose service that runs the upstream
ghcr.io/berriai/litellm:main-stable proxy as part of the same
docker-compose project. Operators bring it up by adding
-f docker-compose.litellm.yml to the up command. The service:
- listens on :4000 (matches the LITELLM_API_BASE example in README)
- reads ANTHROPIC_API_KEY / OPENAI_API_KEY from .env
- has a fixed master_key (sk-litellm-local-master) the operator points
LITELLM_API_KEY at — matches the litellm-config.yaml master_key
- has a healthcheck so dependent services don't race the proxy's
cold-start (~20s for litellm to bind)
litellm-config.yaml.example ships two Anthropic models (sonnet-4-5,
haiku-4-5) wired up; OpenAI entries are commented out behind
OPENAI_API_KEY. The actual litellm-config.yaml is .gitignored so each
operator can shape their model list without leaking it through git.
README.md gains a 'Self-hosted LiteLLM gateway (optional)' subsection
under Self-hosting that walks through the copy-config / set-key /
compose-up flow.
Greptile SummaryThis PR adds an optional
Confidence Score: 3/5Safe to merge after the gitignore gap is closed; the other findings are cosmetic or low-risk defaults. The missing .gitignore entry for litellm-config.yaml is the one concrete gap — the author identified it in the PR description but did not add the line. A contributor who copies the example, customises the master key, and runs git add . will commit the file without any warning. Everything else (German message, hardcoded default key, host.docker.internal vs service name) is style or a minor ergonomics issue that does not affect correctness. docker-compose.litellm.yml for the hardcoded master key and German error string; .gitignore for the missing litellm-config.yaml exclusion.
|
| Filename | Overview |
|---|---|
| docker-compose.litellm.yml | New optional compose service for the LiteLLM proxy; contains a German-language error message and a hardcoded master key that should be an env-var default instead. |
| litellm-config.yaml.example | Well-structured example config; uses env-var references for provider keys correctly, but the hardcoded master_key should align with any env-var approach adopted in the compose file. |
| README.md | New optional LiteLLM setup section; instructs users to use host.docker.internal when the direct service name (litellm:4000) is available and more idiomatic within the compose project. |
Reviews (1): Last reviewed commit: "feat(dev): self-hosted LiteLLM proxy com..." | Re-trigger Greptile
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
|
Thanks for the review — addressed in the latest commit:
On the |
…ore config Follow-up to the review on the self-hosted LiteLLM proxy: - .gitignore: add litellm-config.yaml. The working copy is derived from litellm-config.yaml.example and customised with provider keys + master_key; .env* did not cover this filename, so 'git add .' would silently commit it. - README: clarify the LITELLM_API_BASE value. It is injected into the sandbox harness pods, which run in the kind cluster on a separate Docker network and cannot resolve the 'litellm' compose service name — they reach the proxy via host.docker.internal. Document host.docker.internal:4000 as the value for the kind backend (the default self-hosting path), and note that litellm:4000 only works when running without kind (LOCAL_SANDBOX_URL / brain-inline, all inside the compose project). Verified: from the kind node, 'litellm' is unresolvable while host.docker.internal:4000 returns HTTP 200.
|
Follow-up — pushed
Verified from the kind node: |
Summary
README.mdandCONTRIBUTING.mdtreat "a LiteLLM gateway URL" as a prerequisite without documenting where it comes from. New contributors trying the docker-compose flow either reach for a hosted Berri instance (account + key + cost) or skip the platform entirely because no model calls work without a gateway.This PR adds an optional compose service that runs the upstream
ghcr.io/berriai/litellm:main-stableproxy as part of the same docker-compose project. Operators opt in by adding-f docker-compose.litellm.ymlto the up command:What's included
docker-compose.litellm.yml— service definition. Listens on:4000, has a Python-based healthcheck against/health/liveliness, readsANTHROPIC_API_KEY/OPENAI_API_KEYfrom.env, requiresANTHROPIC_API_KEYto be set (uses${VAR:?...}so misconfig fails at compose-parse time, not at request time).litellm-config.yaml.example— minimal config with two Anthropic models wired up and OpenAI entries commented out behindOPENAI_API_KEY. Master key matches the platform'sLITELLM_API_KEYexample. The actuallitellm-config.yamlis in.gitignore(via.env*pattern? — check during review; happy to add an explicitlitellm-config.yamlentry if not).README.md— new "Self-hosted LiteLLM gateway (optional)" subsection under Self-hosting that walks the copy-config / set-key / compose-up flow.What is unchanged
docker-compose.ymlis untouched. Operators who already have a hosted LiteLLM proxy can keep ignoring the new file.ANTHROPIC_API_KEYonly becomes required if you opt into the new compose file.LITELLM_API_BASE/LITELLM_API_KEYcontract is unchanged.Why not just docs?
The flow is small enough that pointing at LiteLLM's own setup docs would work, but every step (which image, which env vars, which port, which master_key to align with the platform) is something a contributor has to figure out before their first session call works. Shipping the compose file collapses 30 minutes of trial-and-error into one optional command.
Test plan
docker compose -f docker-compose.yml -f docker-compose.litellm.yml up— both services healthyanthropic/claude-haiku-4-5round-trips a messageANTHROPIC_API_KEYunset) fails at compose-parse with a clear message, not at first request