Files
homelab/edge-cache/README.md
T

3.5 KiB
Raw Blame History

Label-managed edge cache

Services opt paths into the shared edge cache with Docker labels. The controller discovers the labels, writes higher-priority Traefik routers, and maintains a single Cloudflare Cache Rule that makes the declared host/path pairs eligible for edge caching.

labels:
  - "xiteng.site.cache.frontend.enabled=true"
  - "xiteng.site.cache.frontend.routers=example,example-http"
  - "xiteng.site.cache.frontend.paths=/static/,/assets/"
  - "xiteng.site.cache.frontend.edge-ttl=604800"
  - "xiteng.site.cache.frontend.browser-ttl=0"
  - "xiteng.site.cache.frontend.stale-while-revalidate=86400"

The policy id (frontend) only needs to be unique inside one Compose service. routers refers to Traefik Docker router names declared on the same service. When omitted, all explicit HTTP routers on the service are used. Each router must declare its entrypoints and service so it can be referenced from the file provider. Existing router middlewares are inherited, so request headers and origin-side authentication are not silently removed.

Field Default Behavior
enabled required Only the exact value true enables a policy.
routers auto Comma-separated Traefik router names on the same container.
paths required Comma-separated directory prefixes. Each must start and end with /; /, traversal and encoded paths are rejected.
hosts from Host() Optional exact hostnames for complex router rules; hosts must be inside xiteng.site.
edge-ttl 604800 Cloudflare TTL in seconds, bounded to 60 seconds365 days.
browser-ttl 0 When non-zero, also overrides the browser Cache-Control TTL.
stale-while-revalidate 86400 Stale revalidation window in seconds.

The generated router only matches GET and HEAD, has priority 1000 above its base router, and adds Cloudflare-CDN-Cache-Control. Cloudflare's managed rule makes extensionless files eligible for cache, respects the TTL header for successful responses, and gives 3xx5xx responses a zero edge TTL.

Declaring a path static is a security decision: every response below the prefix must be public and independent of users, cookies, authorization headers, and request-specific data. Never label HTML, API, callback, admin, download-token, or user-content paths. A Cloudflare cache hit is served before Traefik/ForwardAuth, even though cache misses still inherit the base router's middlewares. Removing a policy does not revoke copies already held by browsers or edge locations; choose bounded TTLs and purge Cloudflare explicitly when previously public content must be withdrawn immediately.

Cloudflare token

Place an untracked API token at secrets/cloudflare_cache_api_token. It needs access to the xiteng.site zone and the permissions required to edit Cache Rules. The existing DNS-01 token is intentionally not reused. The controller remains healthy without this file and reports waiting-for-token; in that state Traefik headers and default-extension caching work, but arbitrary extensionless URLs are not guaranteed to be cached by Cloudflare.

Create the token in Cloudflare, then install it without exposing it in shell history or chat:

./edge-cache/configure-token

Inspect the generated rule without contacting Cloudflare:

docker compose -f edge-cache/compose.yml exec controller \
  node /app/cloudflare.mjs plan

The live controller automatically creates or updates only the rule whose description is Xiteng label-managed static paths; it preserves all unrelated Cache Rules.