fix: stop production overlays defaulting to third-party LLM and online GeoIP (#607) - #608
Conversation
…e GeoIP (#607) On a deploy box with no .env, the production overlay resolved to: LLM_API_BASE_URL: https://api.openai.com/v1 GEO_FORCE_OFFLINE: "false" Neither prod overlay pinned these, so both inherited the base file's local-dev convenience defaults. AI features build their prompts from analysed capture content, so that is a data egress path — in the deployment most likely to hold real operational data, and in direct conflict with the offline requirement. docker-compose.offline.yml already handled this correctly (MMDB-only geo, a localhost LLM). The online production path never received the same treatment. The failure mode is quiet: a developer .env typically overrides LLM_API_BASE_URL to a local or Tailscale host, so it works on the developer's machine and only breaks the guarantee on a fresh deploy box. docker-compose.prod.yml LLM_API_BASE_URL is now REQUIRED (${VAR:?}) — the endpoint must be a deliberate choice, following the same fail-fast pattern as the credentials in #595 rather than trusting an operator to read a doc. GEO_FORCE_OFFLINE defaults to true, matching docker-compose.offline.yml. docker-compose.offline-prod.yml Both restated explicitly, so an air-gapped deployment's guarantee doesn't rest on a default in the file below it. Base docker-compose.yml is unchanged — local dev and CI depend on those defaults, and the base stack is the open testing path. Verified: prod aborts with an actionable message when LLM_API_BASE_URL is unset; prod with it set resolves geo offline and contains zero api.openai.com references; offline-prod still starts air-gapped with no .env; base config unchanged; stack builds and API returns 200; docs build clean. Closes #607 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 53 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughProduction Compose overlays now require explicit LLM endpoints and default GeoIP resolution to offline mode. Environment examples and production-hardening documentation describe local LLM configuration, capture-data egress, and conditions for enabling online GeoIP lookups. ChangesProduction egress controls
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.env.example:
- Around line 144-147: Update the .env.example LLM endpoint documentation to
recommend only reachable local inference servers, removing the OpenAI/API
option. Correct the production overlay explanation to distinguish the overlays:
document that the relevant overlay aborts when unset, while
docker-compose.offline-prod.yml uses a localhost fallback; do not imply every
production overlay aborts.
In `@docker-compose.offline-prod.yml`:
- Line 94: Align the LLM_API_BASE_URL documentation with each overlay’s
behavior: in docker-compose.offline-prod.yml, retain and document the localhost
fallback; in .env.example, remove the claim that every production overlay fails
when the variable is unset; and in docs/operations/production-hardening.rst,
state that the online overlay requires the variable while the offline overlay
uses its default.
In `@docker-compose.prod.yml`:
- Around line 94-96: Set GEO_FORCE_OFFLINE to the literal "true" in
docker-compose.prod.yml lines 94-96 and docker-compose.offline-prod.yml lines
91-95, removing the environment-variable override. In
docs/operations/production-hardening.rst lines 258-261, remove the instruction
to set GEO_FORCE_OFFLINE to false.
- Around line 91-93: Constrain LLM_API_BASE_URL in both
docker-compose.prod.yml:91-93 and docker-compose.offline-prod.yml:91-94 to
validated local-only hostnames and ports rather than accepting arbitrary .env or
CLI values. In the offline overlay, replace the container-localhost default with
an explicitly configured local inference gateway; preserve the required
configuration behavior while preventing external endpoints.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 300284fc-f264-4efb-bbd4-f07595616b9d
📒 Files selected for processing (4)
.env.exampledocker-compose.offline-prod.ymldocker-compose.prod.ymldocs/operations/production-hardening.rst
The docs and .env.example claimed both production overlays abort when LLM_API_BASE_URL is unset, but offline-prod silently fell back to http://localhost:1234/v1 — which resolves to the backend container itself, not to any inference host on the network. An air-gapped operator who trusted that wording would get a stack that starts fine and then fails at request time. Makes offline-prod require the variable, matching prod, so the documented behaviour is true. Also stops .env.example presenting OpenAI as a valid option (it contradicts the offline requirement) and warns that localhost resolves inside the container. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Problem
On a deploy box with no
.env, the production overlay resolved to:Neither prod overlay pinned these, so both inherited the base file's local-dev convenience defaults.
AI features (Story mode, Network Insights) build their prompts from analysed capture content, so the LLM endpoint is a data egress path — in the deployment most likely to hold real operational data, and in direct conflict with the offline requirement in
CLAUDE.md.docker-compose.offline.ymlalready handled this correctly (MMDB-only geo, a localhost LLM). The online production path never received the same treatment.Why it stayed invisible
A developer
.envtypically overridesLLM_API_BASE_URLto a local or Tailscale host. It works on the developer's machine and only breaks the guarantee on a fresh deploy box — which is exactly where it matters.Changes
docker-compose.prod.ymlLLM_API_BASE_URLis now required (${VAR:?}), so the endpoint is always a deliberate choice. Same fail-fast pattern as the credentials in fix: replace shipped default credentials with operator-supplied secrets #595 — abort rather than trust an operator to read a doc.GEO_FORCE_OFFLINEdefaults totrue, matchingdocker-compose.offline.yml.docker-compose.offline-prod.ymlDocs —
production-hardening.rstpreviously said "ensureLLM_API_BASE_URLpoints to a locally-hosted model", advisory prose against a default that actively pointed outward. Now documents enforced behaviour.The base
docker-compose.ymlis unchanged — local dev and CI depend on those defaults, and the base stack is the open testing path.Verification
LLM_API_BASE_URLunsetapi.openai.comreferences.env.env(CI)docker compose up -d --buildCloses #607
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Documentation