# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json # Local stack for development and tests include: - path: benchmark/compose.yml - path: e2e/compose.yml services: # Traefik container that loads the plugin ingress: image: traefik:v3.7 ports: - "8080:80" - "8081:8080" # Dashboard volumes: - ./example/traefik.yml:/etc/traefik/traefik.yml:ro - ./example/dynamic:/etc/traefik/dynamic:ro - .:/plugins-local/src/github.com/eleaven/traedis:ro - certs:/certs:ro # `redis.tls.ca` of example/dynamic/whoami.yml depends_on: certs: condition: service_completed_successfully develop: watch: - path: ./example/traefik.yml action: restart - path: .traefik.yml action: restart - path: ./pkg action: restart - path: go.mod action: restart healthcheck: test: [ "CMD", "traefik", "healthcheck" ] # Requires `ping` in example/traefik.yml interval: 2s timeout: 2s retries: 15 # Redis, where the plugin stores cached responses (>= 8.0 required) cache: image: redis:8-alpine ports: - "6379:6379" # For integration tests: TRAEDIS_REDIS_DSN=redis://localhost:6379/15 volumes: - cache:/data environment: # Bounded memory: the least frequently used entries are evicted first - REDIS_ARGS=--maxmemory 512mb --maxmemory-policy allkeys-lfu healthcheck: test: [ "CMD", "redis-cli", "ping" ] interval: 2s timeout: 2s retries: 15 # Redis that only talks TLS, with the certificate that `certs` makes: exercises `rediss://` → http://localhost:8080/whoami-tls cache-tls: image: redis:8-alpine command: >- redis-server --port 0 --tls-port 6379 --tls-auth-clients no --tls-cert-file /certs/redis.crt --tls-key-file /certs/redis.key --maxmemory 64mb --maxmemory-policy allkeys-lfu volumes: - certs:/certs:ro depends_on: certs: condition: service_completed_successfully healthcheck: test: [ "CMD", "redis-cli", "--tls", "--cacert", "/certs/redis.crt", "-h", "cache-tls", "ping" ] interval: 2s timeout: 2s retries: 15 # Makes the self-signed certificate of cache-tls, once, and exits: it is its own authority certs: image: alpine/openssl:latest entrypoint: [ "sh", "-c" ] command: - >- test -f /certs/redis.crt || { openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -nodes -days 3650 -subj "/CN=cache-tls" -addext "subjectAltName=DNS:cache-tls" -keyout /certs/redis.key -out /certs/redis.crt && chmod 644 /certs/redis.key; } volumes: - certs:/certs # Backend without Cache-Control: exercises `defaultTtl` → http://localhost:8080/whoami-cache (/whoami: without the cache), # stale responses → http://localhost:8080/whoami-stale and `Vary` → http://localhost:8080/whoami-vary # (see example/dynamic/whoami.yml) whoami: image: traefik/whoami:latest # Image backend sending `Cache-Control: max-age`: exercises explicit freshness → http://localhost:8080/placeholder-cache/600x400 # (/placeholder/600x400: without the cache) placeholder: image: ghcr.io/open-placeholder/open-placeholder:sha-8a81d5c # Image processing backend (imgproxy) fetching its images from placeholder: a costly response # → http://localhost:8080/imaging-cache/B_7JSu2g6c6gISXWevLdHUvpMHw_HJm5zrr9TOlxVSk/rs:fill:300:200/plain/http://placeholder:3000/600x400@avif # (/imaging/…: without the cache). Its URLs are signed, as in production: any other one gets a 403. To sign another path: # path=/rs:fill:300:200/plain/http://placeholder:3000/800x600@avif # { xxd -r -p <<< "$IMGPROXY_SALT"; printf %s "$path"; } \ # | openssl dgst -sha256 -mac HMAC -macopt "hexkey:$IMGPROXY_KEY" -binary | basenc --base64url | tr -d = imaging: image: ghcr.io/imgproxy/imgproxy:v3 environment: # Public, for this local stack only: in production, they are secrets IMGPROXY_KEY: 55019804a9d53ce94eae236826ef7ec904fb49992e64c0edacc386a91fc0faf5 IMGPROXY_SALT: b94fa6337853288c8b36abfdad5dab013014bbc82007c7fe3f58b2a4a6a9d7f3 IMGPROXY_LOG_LEVEL: debug IMGPROXY_DEVELOPMENT_ERRORS_MODE: "true" IMGPROXY_USE_ETAG: "true" # answers 304 to If-None-Match → http://localhost:8080/imaging-validate/… (fresh for 2s) healthcheck: test: [ "CMD", "imgproxy", "health" ] interval: 2s timeout: 2s retries: 15 # Redis Insight, to browse the cached entries → http://localhost:5540 insight: image: redis/redisinsight:latest ports: - "5540:5540" environment: RI_REDIS_HOST0: cache RI_REDIS_PORT0: 6379 RI_REDIS_ALIAS0: "Imaging" RI_REDIS_DB0: 0 RI_REDIS_HOST1: cache RI_REDIS_PORT1: 6379 RI_REDIS_ALIAS1: "Placeholder" RI_REDIS_DB1: 1 RI_REDIS_HOST2: cache RI_REDIS_PORT2: 6379 RI_REDIS_ALIAS2: "Whoami" RI_REDIS_DB2: 2 RI_ACCEPT_TERMS_AND_CONDITIONS: "true" RI_DATABASE_MANAGEMENT: "false" volumes: cache: certs: