fix(omniroute): add required WS bridge secret, memory ceiling, shutdown grace period
Cross-checked the deployment against OmniRoute's own docs (docs/reference/ENVIRONMENT.md, docs/guides/DOCKER_GUIDE.md) and found three gaps from the original migration: - OMNIROUTE_WS_BRIDGE_SECRET was entirely missing - ENVIRONMENT.md marks it REQUIRED (production), for the internal Codex Responses WebSocket bridge. docker compose config validated fine without it (compose doesn't know omniroute's own required-var list), so this went unnoticed until checking the docs directly. - No mem_limit/OMNIROUTE_MEMORY_MB - the Docker guide is explicit that the 1024MB default heap is dashboard-only sized; coding-agent workloads (every client this stack has) need OMNIROUTE_MEMORY_MB=8192 and a 10+ GiB container ceiling. Set both. - No stop_grace_period - the guide's --stop-timeout 40 equivalent, so SQLite WAL changes checkpoint back into the main DB file on shutdown instead of getting killed mid-write. Redis checked and confirmed correctly absent - OmniRoute uses SQLite only, no Redis anywhere in its docs. Still open: whether API_PORT actually isolates /dashboard and /api/* from the published port, or bridges everything through (see issue #31) - OmniRoute's own ARCHITECTURE.md doesn't document split-port mode as a real security boundary, and the live "[API Bridge] ... -> dashboard" log line is ambiguous. Waiting on a live curl test against proxy-ai.home before treating that as resolved. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VPZ6TogJiYxG8E4EQBB197
This commit is contained in:
@@ -63,6 +63,9 @@ OMNIROUTE_STORAGE_ENCRYPTION_KEY=
|
|||||||
# Per-deployment salts — random is fine, just needs to be stable:
|
# Per-deployment salts — random is fine, just needs to be stable:
|
||||||
OMNIROUTE_MACHINE_ID_SALT=
|
OMNIROUTE_MACHINE_ID_SALT=
|
||||||
OMNIROUTE_CLI_SALT=
|
OMNIROUTE_CLI_SALT=
|
||||||
|
# Required (production) — shared secret for the internal Codex Responses
|
||||||
|
# WebSocket bridge. Random value, filled in automatically:
|
||||||
|
OMNIROUTE_WS_BRIDGE_SECRET=
|
||||||
# Per-workload virtual keys (one per client that calls the gateway) have no
|
# Per-workload virtual keys (one per client that calls the gateway) have no
|
||||||
# scripted /key/generate equivalent yet — omniroute's key-creation endpoint
|
# scripted /key/generate equivalent yet — omniroute's key-creation endpoint
|
||||||
# needs a dashboard login session, not a static bearer key (see issue #37).
|
# needs a dashboard login session, not a static bearer key (see issue #37).
|
||||||
|
|||||||
@@ -84,6 +84,15 @@ services:
|
|||||||
# default (SSRF guard against public-provider spoofing).
|
# default (SSRF guard against public-provider spoofing).
|
||||||
- OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true
|
- OMNIROUTE_ALLOW_PRIVATE_PROVIDER_URLS=true
|
||||||
- OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS=true
|
- OMNIROUTE_ALLOW_LOCAL_PROVIDER_URLS=true
|
||||||
|
# Required (production) per docs/reference/ENVIRONMENT.md — shared
|
||||||
|
# secret for the internal Codex Responses WebSocket bridge. Missed on
|
||||||
|
# first pass; docker-compose config validated fine without it, but
|
||||||
|
# the docs are explicit this one's required, not optional.
|
||||||
|
- OMNIROUTE_WS_BRIDGE_SECRET=${OMNIROUTE_WS_BRIDGE_SECRET}
|
||||||
|
# Default heap (1024MB) is dashboard-only sized per OmniRoute's own
|
||||||
|
# Docker guide — every client here is a coding CLI, which needs the
|
||||||
|
# larger figure the guide recommends. Paired with mem_limit below.
|
||||||
|
- OMNIROUTE_MEMORY_MB=8192
|
||||||
# Same reasoning as litellm's extra_hosts entry below — ai-stack's bridge
|
# Same reasoning as litellm's extra_hosts entry below — ai-stack's bridge
|
||||||
# network can't resolve search.home on its own.
|
# network can't resolve search.home on its own.
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
@@ -95,6 +104,12 @@ services:
|
|||||||
# to also change omniroute's own internal port config to match.
|
# to also change omniroute's own internal port config to match.
|
||||||
ports:
|
ports:
|
||||||
- "${OMNIROUTE_PORT:-4000}:${OMNIROUTE_API_PORT:-20129}"
|
- "${OMNIROUTE_PORT:-4000}:${OMNIROUTE_API_PORT:-20129}"
|
||||||
|
# 10+ GiB ceiling per OmniRoute's Docker guide, matching
|
||||||
|
# OMNIROUTE_MEMORY_MB=8192 above.
|
||||||
|
mem_limit: 10g
|
||||||
|
# SQLite WAL needs time to checkpoint back into the main DB file on
|
||||||
|
# shutdown — the Docker guide's --stop-timeout 40 equivalent.
|
||||||
|
stop_grace_period: 40s
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
networks: [ai-stack]
|
networks: [ai-stack]
|
||||||
# ponytail: TCP-connect check, not an HTTP /healthz GET — the image has
|
# ponytail: TCP-connect check, not an HTTP /healthz GET — the image has
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ set_if_blank OMNIROUTE_API_KEY_SECRET "$(openssl rand -hex 32)"
|
|||||||
set_if_blank OMNIROUTE_STORAGE_ENCRYPTION_KEY "$(openssl rand -hex 32)"
|
set_if_blank OMNIROUTE_STORAGE_ENCRYPTION_KEY "$(openssl rand -hex 32)"
|
||||||
set_if_blank OMNIROUTE_MACHINE_ID_SALT "$(openssl rand -hex 16)"
|
set_if_blank OMNIROUTE_MACHINE_ID_SALT "$(openssl rand -hex 16)"
|
||||||
set_if_blank OMNIROUTE_CLI_SALT "$(openssl rand -hex 16)"
|
set_if_blank OMNIROUTE_CLI_SALT "$(openssl rand -hex 16)"
|
||||||
|
set_if_blank OMNIROUTE_WS_BRIDGE_SECRET "$(openssl rand -hex 32)"
|
||||||
|
|
||||||
echo "==> resolving SEARXNG_LAN_IP"
|
echo "==> resolving SEARXNG_LAN_IP"
|
||||||
# search.home is a LAN mDNS/local-DNS name — resolvable from this host, just
|
# search.home is a LAN mDNS/local-DNS name — resolvable from this host, just
|
||||||
|
|||||||
Reference in New Issue
Block a user