Add CI workflow, admin frontend, Prometheus/Grafana monitoring, Cloudflare cache rules and worker, Nginx config, CONTRIBUTING.md and update docker-compose.yml

This commit is contained in:
zwitschi committed 2026-08-02 16:50:46 +02:00
1 parent 15a2aaa1a1
commit 15043cb4d1
8 files changed
+314

No files matched your search

+25
View File
@@ -0,0 +1,25 @@
# Cloudflare Cache Rules for Linear Void (per ADR-001)
## Recommended Cache Rules for media.example.com
1. **.ts segments (immutable)**
- Expression: (http.host eq "media.example.com" and http.request.uri.path contains ".ts")
- Cache status: Eligible for cache
- Edge Cache TTL: 1 month (or `Cache-Control: public, max-age=31536000, immutable` from origin)
- Cache Everything: Yes
2. **.m3u8 manifests (live)**
- Expression: (http.host eq "media.example.com" and http.request.uri.path contains ".m3u8")
- Cache status: Eligible for cache
- Edge Cache TTL: 10 seconds
- Cache-Control: public, max-age=10, must-revalidate
3. **Static assets**
- Expression: (http.host eq "example.com" and http.request.uri.path contains ".js" or http.request.uri.path contains ".css")
- Edge Cache TTL: 1 year (with hash in filename for immutable caching)
**Tiered Cache**: Enable Smart Tiered Cache for R2 custom domain to reduce origin requests.
**WAF**: Enable basic rate limiting and bot management for /ws and admin routes.
These rules ensure high cache hit ratio for .ts segments while keeping live manifests fresh. Monitor cache hit ratio in Cloudflare analytics.
+21
View File
@@ -0,0 +1,21 @@
// Cloudflare Worker for advanced cache rules and WAF (ADR-001)
addEventListener("fetch", (event) => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
const url = new URL(request.url);
// Add immutable cache headers for .ts segments
if (url.pathname.endsWith(".ts")) {
const response = await fetch(request);
const headers = new Headers(response.headers);
headers.set("Cache-Control", "public, max-age=31536000, immutable");
return new Response(response.body, {
status: response.status,
headers,
});
}
return fetch(request);
}