Sign inSign up

bouinecache/bouine

By bouinecache

•Updated about 14 hours ago

Bouine is a Cloud Native, distributed read/write-through HTTP cache

Image
Networking
Web servers
Content management system
0

10K+

bouinecache/bouine repository overview

⁠bouine

⚡ Bouine is a cloud-native HTTP reverse-proxy cache in Go — RFC 9111 compliant, zero-alloc hit path, gossip clustering, no external K/V store.

Designed from day one for Kubernetes, multi-instance clustering, and first-class observability. No Redis, no Memcached, no external database — peers discover each other and share cache state over gossip.

⁠Highlights

RFC 911193.7% (342/365) on http-tests/cache-tests. Freshness, validation, Vary, Cache-Control, stale-while-revalidate, stale-if-error, heuristic caching, CDN-Cache-Control, must-understand, negative caching.
Zero-alloc hit pathNo heap allocations once warm; sub-microsecond cache hits. Benchmark-gated in CI (allocs/op == 0).
Gossip clusteringmemberlist peer discovery + consistent-hash ring + peer fetch (HTTP/2 over mTLS). Strong / eventual / full-replication consistency modes. No external K/V store.
Two-tier storageSharded in-RAM hot tier (SIEVE eviction, lock-free ban check) + mmap-backed warm tier (write-ahead index log, background compaction).
InvalidationExact purge (single + batch), predicate-based bans (lazy), soft-purge refresh, surrogate keys, Cloudflare CDN propagation.
Origin resilienceConnection pool, active + passive health checks, hedged requests, request collapsing (single-flight), circuit breaker, per-pool upstream TLS (mTLS, custom CA, SPKI pinning).
Observability-firstPrometheus metrics, OpenTelemetry traces (OTLP), structured slog access logs, pprof, embedded operator dashboard.
Operator dashboardLive UI on the admin port: overview, cluster ring, invalidation log, performance page, config viewer. Session-cookie auth.
DistrolessNon-root, multi-arch (amd64 + arm64), minimal attack surface. SBOM + cosign signed.

⁠Quick start

docker pull bouinecache/bouine:latest
docker run --rm -p 8080:80 -p 9000:9000 bouinecache/bouine:latest
  • Data plane (proxy/cache): container port 80
  • Admin + metrics + dashboard: container port 9000

The default image ships a minimal config at /etc/bouine/config.yaml so the container starts without a volume mount. For production, mount your own config there, or use the Helm chart so Kubernetes manages the ConfigMap.

curl -sf http://127.0.0.1:9000/healthz

⁠Kubernetes (Helm)

The chart is published as a Helm repository and indexed on Artifact Hub⁠:

helm repo add bouine https://charts.bouine.org
helm repo update

helm install bouine bouine/bouine \
  --namespace bouine --create-namespace \
  --set "config.upstream_pools[0].name=app" \
  --set "config.upstream_pools[0].targets[0]=app.default.svc:8080" \
  --set "config.routes[0].pool=app" \
  --set config.cluster.enabled=true

This deploys a 3-replica StatefulSet with gossip clustering, a headless Service for peer discovery, and a PodDisruptionBudget. See values.yaml⁠ for all options.

⁠Invalidation

All write endpoints on the admin port (:9000) require a bearer token. If no token is configured, bouine generates one at startup and logs it as a WARN.

# Exact purge of a single URL
curl -X POST http://127.0.0.1:9000/v1/purge \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"url":"https://example.com/page"}'

# Batch purge (up to 1000 URLs per request)
curl -X POST http://127.0.0.1:9000/v1/purge/batch \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"urls":["https://example.com/a","https://example.com/b"]}'

# Predicate-based ban (lazy, evaluated on lookup)
curl -X POST http://127.0.0.1:9000/v1/ban \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"path_regex":"^/products/.*","host_regex":"example\\.com"}'

# Soft-purge: revalidate on next access
curl -X POST http://127.0.0.1:9000/v1/refresh \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"url":"https://example.com/page"}'

When the optional Cloudflare integration is configured (cloudflare.zone_id + cloudflare.api_token), purge/ban/refresh operations are automatically propagated to the downstream Cloudflare CDN.

⁠Operator dashboard

A live dashboard is served on the admin port at /dashboard/. Authentication is a session login: browse to /dashboard/login and enter your admin token (there is no separate username/password). A session cookie is then set for subsequent requests. Pages include overview, cluster ring, invalidation log, performance (latency percentiles, SLO compliance), routes, and config.

⁠Admin API endpoints

MethodPathDescription
GET/healthzLiveness probe.
GET/readyzReadiness probe (?detail=1 for per-condition state).
GET/versionBuild version, commit, date.
GET/drainK8s preStop hook (marks not-ready, blocks for drain duration).
GET/metricsPrometheus metrics.
GET/v1/cluster/peersList live cluster peers.
POST/v1/purgeExact purge of a single URL.
POST/v1/purge/batchBatch purge (up to 1000 URLs).
POST/v1/banPredicate-based ban.
POST/v1/refreshSoft-purge (revalidate on next access).
GET/v1/auth/checkValidate bearer token.
GET/v1/cloudflare/statusCloudflare integration state.
GET/debug/pprof/*pprof endpoints (heap, goroutine, block, mutex, threadcreate, profile, trace).

⁠Go SDK

A typed client for the admin API is available at pkg/bouineapi⁠:

import "github.com/bouine-cache/bouine/pkg/bouineapi"

client := bouineapi.NewClient("http://bouine-admin:9000", token)
client.Purge(ctx, "https://example.com/page")

⁠Image variants

TagDescription
latestLatest stable release.
vX.Y.ZSpecific release version.

All tags are distroless, run as non-root, and are published for linux/amd64 and linux/arm64. Images ship with an SBOM and are signed with cosign.


Full documentation, configuration reference, and operations guides: https://bouine.org⁠

Tag summary

Content type

Image

Digest

sha256:34ed11dcc…

Size

11.3 MB

Last updated

8 days ago

docker pull bouinecache/bouine