From 152dad0a409e61c8e85dfba2948882594c53a264 Mon Sep 17 00:00:00 2001 From: Viktor Barzin Date: Fri, 12 Jun 2026 00:25:44 +0000 Subject: [PATCH] =?UTF-8?q?android-emulator:=20dedicated=20rate-limit=20?= =?UTF-8?q?=E2=80=94=20noVNC's=20module=20storm=20tripped=20the=20shared?= =?UTF-8?q?=2010/50=20limiter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Viktor's 'VNC stuck loading forever' (remote network): noVNC 1.3 is unbundled and fetches ~60 ES modules in parallel on page open; the shared Traefik rate-limit (average 10, burst 50) 429s the tail and noVNC's loader waits on the missing modules indefinitely (reproduced: 38x429 in a 90-request burst through the ingress). Adds a dedicated 50/300 android-emulator-rate-limit middleware (actualbudget/immich pattern) and opts both emulator ingresses out of the shared limiter. --- stacks/android-emulator/main.tf | 10 ++++++++ stacks/traefik/modules/traefik/middleware.tf | 24 ++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/stacks/android-emulator/main.tf b/stacks/android-emulator/main.tf index 1b70b471..10220999 100644 --- a/stacks/android-emulator/main.tf +++ b/stacks/android-emulator/main.tf @@ -231,6 +231,11 @@ module "ingress-internal" { extra_annotations = { "gethomepage.dev/enabled" = "false" } + # noVNC loads ~60 unbundled ES modules in parallel; the default 10/50 + # limiter 429s the tail and the loader hangs forever. Dedicated limiter, + # same pattern as actualbudget/immich. + skip_default_rate_limit = true + extra_middlewares = ["traefik-android-emulator-rate-limit@kubernetescrd"] } # Remote (off-LAN) screen access — Authentik-gated at the edge; WebSockets @@ -246,4 +251,9 @@ module "ingress-public" { host = "android-emulator" service_name = kubernetes_service.novnc.metadata[0].name tls_secret_name = var.tls_secret_name + # noVNC loads ~60 unbundled ES modules in parallel; the default 10/50 + # limiter 429s the tail and the loader hangs forever. Dedicated limiter, + # same pattern as actualbudget/immich. + skip_default_rate_limit = true + extra_middlewares = ["traefik-android-emulator-rate-limit@kubernetescrd"] } diff --git a/stacks/traefik/modules/traefik/middleware.tf b/stacks/traefik/modules/traefik/middleware.tf index ef34f991..0378d0c3 100644 --- a/stacks/traefik/modules/traefik/middleware.tf +++ b/stacks/traefik/modules/traefik/middleware.tf @@ -453,3 +453,27 @@ resource "kubernetes_manifest" "middleware_retry" { depends_on = [helm_release.traefik] } + +# android-emulator noVNC rate limit. noVNC 1.3 ships unbundled: vnc.html +# pulls ~60 ES modules in parallel on every page open, and the default +# 10/50 limiter 429s the tail — the loader then waits forever on the +# missing modules ("stuck on loading", verified 38x429 at a 90-request +# burst on 2026-06-12). Same remedy as actualbudget/immich. +resource "kubernetes_manifest" "middleware_android_emulator_rate_limit" { + manifest = { + apiVersion = "traefik.io/v1alpha1" + kind = "Middleware" + metadata = { + name = "android-emulator-rate-limit" + namespace = kubernetes_namespace.traefik.metadata[0].name + } + spec = { + rateLimit = { + average = 50 + burst = 300 + } + } + } + + depends_on = [helm_release.traefik] +}