tripit: dedicated 100/1000 rate-limit — photo grid 429s on the default 10/50
Viktor hit a wall of 429s scrolling the new trip Photos tab: every Immich thumbnail proxies through tripit's /api, so a few-hundred-photo trip is that many parallel GETs from one IP — far past the shared Traefik limiter's average 10 / burst 50. Fourth instance of the parallel-asset pattern (ha-sofia, ActualBudget, noVNC); same cure: dedicated tripit-rate-limit middleware (average 100, burst 1000) + skip_default_rate_limit on the main tripit ingress only. The token-gated calendar/email/slack carve-outs keep the strict default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
e8a4eb0f05
commit
eef4dc7f63
2 changed files with 31 additions and 0 deletions
|
|
@ -319,6 +319,31 @@ resource "kubernetes_manifest" "middleware_actualbudget_rate_limit" {
|
||||||
depends_on = [helm_release.traefik]
|
depends_on = [helm_release.traefik]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TripIt-specific rate limit. The trip Photos tab proxies every Immich
|
||||||
|
# thumbnail through tripit's own /api — scrolling a few-hundred-photo trip
|
||||||
|
# fires that many parallel image GETs from one client IP, and the default
|
||||||
|
# 10/50 limiter 429s the tail (fourth instance of the parallel-asset
|
||||||
|
# pattern, after ha-sofia, ActualBudget, and noVNC). Burst must absorb a
|
||||||
|
# full trip-gallery scroll plus lightbox prefetches.
|
||||||
|
resource "kubernetes_manifest" "middleware_tripit_rate_limit" {
|
||||||
|
manifest = {
|
||||||
|
apiVersion = "traefik.io/v1alpha1"
|
||||||
|
kind = "Middleware"
|
||||||
|
metadata = {
|
||||||
|
name = "tripit-rate-limit"
|
||||||
|
namespace = kubernetes_namespace.traefik.metadata[0].name
|
||||||
|
}
|
||||||
|
spec = {
|
||||||
|
rateLimit = {
|
||||||
|
average = 100
|
||||||
|
burst = 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
depends_on = [helm_release.traefik]
|
||||||
|
}
|
||||||
|
|
||||||
# Compress responses to clients at the entrypoint level (outermost).
|
# Compress responses to clients at the entrypoint level (outermost).
|
||||||
# Applied at websecure entrypoint so all responses get compressed.
|
# Applied at websecure entrypoint so all responses get compressed.
|
||||||
# Uses includedContentTypes (whitelist) instead of excludedContentTypes:
|
# Uses includedContentTypes (whitelist) instead of excludedContentTypes:
|
||||||
|
|
|
||||||
|
|
@ -760,6 +760,12 @@ module "ingress" {
|
||||||
name = "tripit"
|
name = "tripit"
|
||||||
port = 8080
|
port = 8080
|
||||||
tls_secret_name = var.tls_secret_name
|
tls_secret_name = var.tls_secret_name
|
||||||
|
# The Photos tab proxies Immich thumbnails through /api — a trip-gallery
|
||||||
|
# scroll is hundreds of parallel image GETs, far past the default 10/50
|
||||||
|
# limiter. Dedicated 100/1000 middleware (stacks/traefik middleware.tf);
|
||||||
|
# the calendar/email carve-out ingresses below stay on the default.
|
||||||
|
skip_default_rate_limit = true
|
||||||
|
extra_middlewares = ["traefik-tripit-rate-limit@kubernetescrd"]
|
||||||
}
|
}
|
||||||
|
|
||||||
# Calendar feed carve-out for the same host: path /api/calendar served by the
|
# Calendar feed carve-out for the same host: path /api/calendar served by the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue