Zwei Einstellungen im Deployment liessen einen Video-Upload scheitern, bevor die Anwendung ueberhaupt antworten konnte — beide Male mit einer HTML-Fehlerseite, die im Browser als "Unexpected token '<'" ankam: 1. Der Ingress trug keinerlei Timeout-Annotation. ingress-nginx wartet dann nur 60 Sekunden je Phase und liefert danach eine eigene HTML-504-Seite. Ein Video-Upload braucht regelmaessig laenger: erst muessen bis zu 100 MB ueber die Leitung, danach rechnet ffmpeg das Video fuers Web um. proxy-read-timeout und proxy-send-timeout stehen jetzt auf 600s — bewusst oberhalb des harten ffmpeg-Zeitlimits von 5 Minuten, damit im Zweifel die Anwendung selbst mit einer verwertbaren JSON-Meldung abbricht statt nginx die Verbindung zu kappen. 2. Das Speicherlimit von 512Mi war fuer einen 100-MB-Upload zu knapp: request.formData() laedt den multipart-Body vollstaendig in den Speicher, und der Kernel beendet den Prozess bei Ueberschreitung (OOMKilled). Limit auf 1Gi, Request auf 512Mi. Der CPU-Request steigt von 100m auf 500m, weil ffmpeg CPU-gebunden ist und mit 100m ein Vielfaches der Zeit braucht — bewusst weiterhin ohne CPU-Limit, das wuerde den Transcode auch auf einem freien Knoten drosseln. Der Kommentar nennt zusaetzlich das davon unabhaengige Origin-Zeitlimit eines vorgeschalteten CDN (bei Cloudflare 100 Sekunden, Fehler 524), das sich hier nicht beeinflussen laesst.
67 lines
3.1 KiB
YAML
67 lines
3.1 KiB
YAML
# Setzt einen bereits im Cluster laufenden Ingress-Controller voraus (z.B.
|
|
# ingress-nginx) sowie optional cert-manager fuer automatisches TLS. Host
|
|
# unten anpassen (muss zu NEXT_PUBLIC_SITE_URL in 01-configmap.yaml passen).
|
|
#
|
|
# X-Forwarded-For: ingress-nginx setzt den Header standardmaessig korrekt
|
|
# (verwirft einen vom Client mitgeschickten Wert), lib/rate-limit.ts vertraut
|
|
# genau darauf — bei einem ANDEREN Ingress-Controller/zusaetzlichen Proxy
|
|
# davor unbedingt pruefen, dass er sich genauso verhaelt, siehe Kommentar in
|
|
# lib/rate-limit.ts.
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: wabenhain
|
|
namespace: wabenhain
|
|
annotations:
|
|
# Nur relevant, falls cert-manager installiert ist — sonst diese beiden
|
|
# Zeilen und den "tls:"-Block unten entfernen und Host per HTTP betreiben
|
|
# oder TLS auf andere Weise terminieren.
|
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
# ingress-nginx laesst ohne diese Annotation standardmaessig nur 1 MB pro
|
|
# Request durch — weit unter dem Bild- (25 MB, lib/uploads.ts
|
|
# MAX_UPLOAD_BYTES) und erst recht dem Video-Limit (100 MB, lib/uploads.ts
|
|
# MAX_UPLOAD_VIDEO_BYTES) der Admin-Uploads. Ohne diese Zeile bricht
|
|
# nginx jeden Upload jenseits von 1 MB vor der App ab (Verbindungsabbruch
|
|
# ohne verwertbare Fehlermeldung im Browser) — 110m deckt das groessere
|
|
# der beiden Limits (100 MB) plus etwas Spielraum fuer den
|
|
# multipart/form-data-Overhead ab.
|
|
nginx.ingress.kubernetes.io/proxy-body-size: "110m"
|
|
# Ohne diese drei Annotationen wartet ingress-nginx nur 60 Sekunden je
|
|
# Phase und liefert danach eine eigene HTML-Fehlerseite (504) aus. Der
|
|
# Video-Upload braucht regelmaessig laenger: erst muessen bis zu 100 MB
|
|
# ueber die Leitung, danach rechnet ffmpeg das Video fuers Web um (siehe
|
|
# lib/video-transcode.ts). Im Browser kam davon nur an, dass die Antwort
|
|
# kein JSON war ("Unexpected token '<', "<!DOCTYPE "... is not valid
|
|
# JSON") — die Ursache war daraus nicht ablesbar.
|
|
#
|
|
# 600s deckt den langsamsten realistischen Fall ab und liegt bewusst
|
|
# oberhalb des harten ffmpeg-Zeitlimits von 5 Minuten
|
|
# (TRANSCODE_TIMEOUT_MS in lib/video-transcode.ts): so bricht im Zweifel
|
|
# die Anwendung selbst mit einer verwertbaren JSON-Meldung ab, statt dass
|
|
# nginx die Verbindung vorher kappt.
|
|
#
|
|
# Achtung: sitzt zusaetzlich ein CDN davor (z.B. Cloudflare), gilt dessen
|
|
# eigenes Origin-Zeitlimit unabhaengig hiervon weiter — bei Cloudflare
|
|
# sind das 100 Sekunden (Fehler 524), ebenfalls als HTML-Seite.
|
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
|
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
|
|
spec:
|
|
ingressClassName: nginx
|
|
tls:
|
|
- hosts:
|
|
- shop.example.com
|
|
secretName: wabenhain-tls
|
|
rules:
|
|
- host: shop.example.com
|
|
http:
|
|
paths:
|
|
- path: /
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: wabenhain-app
|
|
port:
|
|
number: 80
|