From b4dc83949e04796b0151ee77c8654ed7727e56bb Mon Sep 17 00:00:00 2001 From: ArthurErlich Date: Wed, 2 Sep 2026 22:28:25 +0200 Subject: [PATCH] feat(litellm): add Redis for router state/rate-limits/budgets/cache MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit New redis service (redis:7-alpine, password-protected, no persistence volume — everything it holds is cache/coordination state). litellm gets REDIS_HOST/REDIS_PORT/REDIS_PASSWORD, which is all LiteLLM needs to use it for router state, rate limits/budgets, and cache invalidation — no litellm-config.yaml block required (docs.litellm.ai/docs/proxy/caching). REDIS_PASSWORD added to .env.example and update.sh's auto-generated secrets. Co-Authored-By: Claude Sonnet 5 --- .env.example | 3 +++ docker-compose.yml | 24 ++++++++++++++++++++++++ litellm-config.yaml | 5 +++-- scripts/update.sh | 1 + 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.env.example b/.env.example index 5b3cffd..a226286 100644 --- a/.env.example +++ b/.env.example @@ -39,6 +39,9 @@ LITELLM_PORT=4000 LITELLM_MASTER_KEY= LITELLM_SALT_KEY= LITELLM_DB_PASSWORD= +# Backs litellm's router state/rate-limits/budgets/cache invalidation +# (the redis service). Random value, filled in automatically — leave blank. +REDIS_PASSWORD= # Admin UI login (https:///ui). Without these, LiteLLM falls back to # username "admin" / password = LITELLM_MASTER_KEY — set these instead so the # master key never has to be typed into the browser. UI_PASSWORD is filled diff --git a/docker-compose.yml b/docker-compose.yml index 528e4b3..7cf9bc0 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -143,6 +143,8 @@ services: condition: service_healthy llama-server: condition: service_started + redis: + condition: service_healthy volumes: - ./litellm-config.yaml:/app/config.yaml:ro # LITELLM_MASTER_KEY / LITELLM_SALT_KEY come straight from .env via env_file @@ -151,6 +153,12 @@ services: env_file: .env environment: - DATABASE_URL=postgresql://litellm:${LITELLM_DB_PASSWORD}@litellm-db:5432/litellm + # Setting these is all LiteLLM needs to use Redis for router state, + # rate limits/budgets, and cache invalidation — no extra config.yaml + # block required. See https://docs.litellm.ai/docs/proxy/caching. + - REDIS_HOST=redis + - REDIS_PORT=6379 + - REDIS_PASSWORD=${REDIS_PASSWORD} # The litellm container only joins the ai-stack bridge network, which has # no visibility into the LAN's mDNS/local-DNS names — search.home won't # resolve without this. Set SEARXNG_LAN_IP in .env to its stable LAN IP @@ -191,6 +199,22 @@ services: timeout: 5s retries: 10 + # Backs litellm's router state, rate limits/budgets, and cache + # invalidation (see the litellm service's REDIS_* env vars above). + # ponytail: no persistence volume — everything litellm stores here is + # cache/coordination state it's fine to lose on restart, not source data. + redis: + image: redis:7-alpine + container_name: redis + command: ["redis-server", "--requirepass", "${REDIS_PASSWORD}"] + restart: unless-stopped + networks: [ai-stack] + healthcheck: + test: ["CMD-SHELL", "redis-cli -a ${REDIS_PASSWORD} ping | grep -q PONG"] + interval: 5s + timeout: 5s + retries: 10 + # Separate Postgres instance (with the pgvector extension) for the # knowledgebase — NOT the same database as litellm-db, which is plain # postgres:16-alpine and has no vector extension installed. See diff --git a/litellm-config.yaml b/litellm-config.yaml index 9ca6882..8b81690 100644 --- a/litellm-config.yaml +++ b/litellm-config.yaml @@ -56,8 +56,9 @@ router_settings: # ponytail: LiteLLM's request-prioritization scheduler is beta (see # docs/proxy-request-priority.md) — exact settings key/shape must be # confirmed against LiteLLM's current docs and smoke-tested against - # llama.cpp before workloads depend on it. Single-instance deployment, - # no Redis configured — add one only if the scheduler turns out to need it. + # llama.cpp before workloads depend on it. Redis is available (see the + # litellm service's REDIS_* env vars in docker-compose.yml) if the + # scheduler needs shared state for it. enable_priority_scheduling: true general_settings: diff --git a/scripts/update.sh b/scripts/update.sh index d4f063f..2f13689 100644 --- a/scripts/update.sh +++ b/scripts/update.sh @@ -36,6 +36,7 @@ echo "==> filling in missing secrets" set_if_blank LITELLM_MASTER_KEY "$(openssl rand -hex 32)" set_if_blank LITELLM_SALT_KEY "$(openssl rand -hex 32)" set_if_blank LITELLM_DB_PASSWORD "$(openssl rand -hex 32)" +set_if_blank REDIS_PASSWORD "$(openssl rand -hex 32)" set_if_blank UI_PASSWORD "$(openssl rand -hex 16)" set_if_blank PGVECTOR_DB_PASSWORD "$(openssl rand -hex 32)" set_if_blank MEMORY_RETRIEVAL_API_KEY "$(openssl rand -hex 32)"