Deployment

Docker

docker run -d -p 8080:8080 \
  -v zerocache-data:/data \
  ghcr.io/shramanb113/zerocache:latest

# semantic near-match tier: same image, tier compiled in
docker run -d -p 8080:8080 -e ZEROCACHE_SEMANTIC=1 \
  ghcr.io/shramanb113/zerocache:semantic

No server-side provider credentials needed — every caller brings its own key per request.

Docker Compose (with Redis)

services:
  zerocache:
    image: ghcr.io/shramanb113/zerocache:latest
    ports: ["8080:8080"]
    environment:
      ZEROCACHE_STORAGE_BACKEND: redis
      ZEROCACHE_REDIS_URL: redis://redis:6379
    depends_on: [redis]
  redis:
    image: redis:7-alpine

Kubernetes / multi-replica

Set ZEROCACHE_STORAGE_BACKEND=redis so every replica shares one store. Redis writes are last-write-wins with no distributed lock — content-addressing means two replicas racing to fill the same key both compute the same value, so this is safe. AddZEROCACHE_CROSS_REPLICA_COALESCING=1 to also collapse concurrent identical single-key misses across replicas via a Redis lock, saving the duplicate upstream calls. The semantic tier works multi-replica on redis too, via a Redis Stream change-feed (needs Redis ≥ 6.2). /health and /ready are your liveness/readiness probes;GET /metrics is Prometheus text specifically so a scrape-and-sum()aggregates across pods.

Environment variables

VariablePurpose
ZEROCACHE_PORTListen port (default 8080), binds 0.0.0.0
ZEROCACHE_STORAGE_BACKENDsled (default) or redis
ZEROCACHE_STORAGE_PATH / ZEROCACHE_REDIS_URLsled data dir (./data, /data in Docker) / Redis URL (redis://127.0.0.1:6379)
ZEROCACHE_TTL_SECONDSUnset by default — entries never expire. 0 or unparseable is treated as unset.
ZEROCACHE_CROSS_REPLICA_COALESCINGOpt-in (1/true/yes), redis backend only. Redis-lock single-flight so N replicas make one upstream call for the same single-key miss.
ZEROCACHE_SEMANTIC1 enables the local-embedder near-match tier (--features semantic / :semantic image only). Fail-fast on embedder-load failure.
ZEROCACHE_SEMANTIC_THRESHOLD / _MATCH_UNIT / _POLL_MS / _INDEX_MAXLENSemantic tier: cosine threshold (0.97), fuzzy span (last-user), redis change-feed XREAD BLOCK ceiling (2000ms), stream cap (100000)
ZEROCACHE_CHAT_PROVIDERS / ZEROCACHE_MESSAGES_PROVIDERSAdd or repoint chat / messages providers: "name=url,…"
ZEROCACHE_OPENAI_BASE_URL / _MISTRAL_ / _GEMINI_ / _HUGGINGFACE_BASE_URLOverride embeddings for self-hosted, wire-compatible endpoints
ZEROCACHE_AZURE_OPENAI_BASE_URL / _AZURE_FOUNDRY_BASE_URLAzure resource hostnames — azure only registers as a provider once one of these is set
ZEROCACHE_AZURE_AUTH_MODEbearer (Entra token, default) or api-key
ZEROCACHE_BEDROCK_REGIONDefault AWS region for Bedrock requests that don't specify one
ZEROCACHE_VERTEX_PROJECT / _VERTEX_LOCATIONDefault GCP project/location for Vertex AI requests that don't specify one
OTEL_EXPORTER_OTLP_ENDPOINT / RUST_LOGUnset → console logging only. Set the OTLP endpoint for OpenTelemetry gRPC trace export; RUST_LOG defaults to info.

CI/CD

Every push runs build / test / test-redis /build-musl / build-semantic / clippy -D warnings /fmt / dashboard. On a push to master, a separate workflow builds and publishes the :latest and :semantic images to GHCR after CI passes. The :latest image is FROM scratch plus one static musl binary — ~14.7 MB, no shell, no libc, no CA bundle.