[traefik] Add global compress middleware to fix response compression
The rewrite-body plugin (rybbit analytics, anti-AI trap links) requires strip-accept-encoding to work, which killed HTTP compression for 50+ services. This adds Traefik's built-in compress middleware at the websecure entrypoint level to re-compress responses to clients after rewrite-body has modified them. Uses includedContentTypes whitelist (not excludedContentTypes) so only text-based types are compressed. SSE, WebSocket, gRPC, and binary downloads are unaffected. Measured improvement on ha-sofia: - app.js: 540KB → 167KB (3.2x) - core.js: 52KB → 19KB (2.7x) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
e80b2f026f
commit
4c8e5bea0b
2 changed files with 54 additions and 1 deletions
|
|
@ -33,7 +33,7 @@ resource "helm_release" "traefik" {
|
||||||
|
|
||||||
values = [yamlencode({
|
values = [yamlencode({
|
||||||
deployment = {
|
deployment = {
|
||||||
replicas = 3
|
replicas = 3
|
||||||
terminationGracePeriodSeconds = 60
|
terminationGracePeriodSeconds = 60
|
||||||
lifecycle = {
|
lifecycle = {
|
||||||
preStop = {
|
preStop = {
|
||||||
|
|
@ -123,6 +123,9 @@ resource "helm_release" "traefik" {
|
||||||
tls = {
|
tls = {
|
||||||
enabled = true
|
enabled = true
|
||||||
}
|
}
|
||||||
|
middlewares = [
|
||||||
|
"traefik-compress@kubernetescrd",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
http3 = {
|
http3 = {
|
||||||
enabled = true
|
enabled = true
|
||||||
|
|
|
||||||
|
|
@ -277,6 +277,56 @@ resource "kubernetes_manifest" "middleware_strip_accept_encoding" {
|
||||||
depends_on = [helm_release.traefik]
|
depends_on = [helm_release.traefik]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Re-compress responses to clients after rewrite-body plugin has modified them.
|
||||||
|
# Applied at websecure entrypoint level (outermost), so the response path is:
|
||||||
|
# backend → rewrite-body modifies uncompressed HTML → compress gzips → client.
|
||||||
|
# Uses includedContentTypes (whitelist) instead of excludedContentTypes:
|
||||||
|
# - Only compresses text-based types that benefit from compression
|
||||||
|
# - Binary types (images, video, zip) are never compressed (no wasted CPU)
|
||||||
|
# - SSE (text/event-stream) is not listed = not compressed (safe for streaming)
|
||||||
|
# - WebSocket is safe regardless (Hijacker interface bypasses compress)
|
||||||
|
# - gRPC is hardcoded excluded in Traefik source (always safe)
|
||||||
|
resource "kubernetes_manifest" "middleware_compress" {
|
||||||
|
manifest = {
|
||||||
|
apiVersion = "traefik.io/v1alpha1"
|
||||||
|
kind = "Middleware"
|
||||||
|
metadata = {
|
||||||
|
name = "compress"
|
||||||
|
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||||
|
}
|
||||||
|
spec = {
|
||||||
|
compress = {
|
||||||
|
minResponseBodyBytes = 1024
|
||||||
|
includedContentTypes = [
|
||||||
|
"text/html",
|
||||||
|
"text/css",
|
||||||
|
"text/plain",
|
||||||
|
"text/xml",
|
||||||
|
"text/javascript",
|
||||||
|
"application/javascript",
|
||||||
|
"application/json",
|
||||||
|
"application/xml",
|
||||||
|
"application/xhtml+xml",
|
||||||
|
"application/rss+xml",
|
||||||
|
"application/atom+xml",
|
||||||
|
"image/svg+xml",
|
||||||
|
"application/wasm",
|
||||||
|
"font/woff2",
|
||||||
|
"font/woff",
|
||||||
|
"font/ttf",
|
||||||
|
"application/manifest+json",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
field_manager {
|
||||||
|
force_conflicts = true
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [helm_release.traefik]
|
||||||
|
}
|
||||||
|
|
||||||
# ForwardAuth middleware to block known AI bot User-Agents
|
# ForwardAuth middleware to block known AI bot User-Agents
|
||||||
resource "kubernetes_manifest" "middleware_ai_bot_block" {
|
resource "kubernetes_manifest" "middleware_ai_bot_block" {
|
||||||
manifest = {
|
manifest = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue