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:semanticNo 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-alpineKubernetes / 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
| Variable | Purpose |
|---|---|
ZEROCACHE_PORT | Listen port (default 8080), binds 0.0.0.0 |
ZEROCACHE_STORAGE_BACKEND | sled (default) or redis |
ZEROCACHE_STORAGE_PATH / ZEROCACHE_REDIS_URL | sled data dir (./data, /data in Docker) / Redis URL (redis://127.0.0.1:6379) |
ZEROCACHE_TTL_SECONDS | Unset by default — entries never expire. 0 or unparseable is treated as unset. |
ZEROCACHE_CROSS_REPLICA_COALESCING | Opt-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_SEMANTIC | 1 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_MAXLEN | Semantic tier: cosine threshold (0.97), fuzzy span (last-user), redis change-feed XREAD BLOCK ceiling (2000ms), stream cap (100000) |
ZEROCACHE_CHAT_PROVIDERS / ZEROCACHE_MESSAGES_PROVIDERS | Add or repoint chat / messages providers: "name=url,…" |
ZEROCACHE_OPENAI_BASE_URL / _MISTRAL_ / _GEMINI_ / _HUGGINGFACE_BASE_URL | Override embeddings for self-hosted, wire-compatible endpoints |
ZEROCACHE_AZURE_OPENAI_BASE_URL / _AZURE_FOUNDRY_BASE_URL | Azure resource hostnames — azure only registers as a provider once one of these is set |
ZEROCACHE_AZURE_AUTH_MODE | bearer (Entra token, default) or api-key |
ZEROCACHE_BEDROCK_REGION | Default AWS region for Bedrock requests that don't specify one |
ZEROCACHE_VERTEX_PROJECT / _VERTEX_LOCATION | Default GCP project/location for Vertex AI requests that don't specify one |
OTEL_EXPORTER_OTLP_ENDPOINT / RUST_LOG | Unset → 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.