62 lines
3.4 KiB
YAML
62 lines
3.4 KiB
YAML
# File uploads: a second Ingress on the same host, for one path.
|
|
#
|
|
# A SEPARATE OBJECT, NOT A FOURTH PATH IN 06-ingress.yaml. ingress-nginx applies an Ingress's
|
|
# annotations to every path that object declares, so the only way to give /api/uploads/ a larger
|
|
# body ceiling without handing the same ceiling to every API route is an object of its own. The
|
|
# controller merges both Ingresses into one server for the host and picks the longest matching
|
|
# prefix per request, so /api/uploads/ lands here and everything else under /api/ keeps the 4m of
|
|
# the main Ingress.
|
|
#
|
|
# PATCH ITS HOST LIKE THE MAIN ONE. An overlay that rewrites `jarvis.example.com` in 06-ingress.yaml
|
|
# must rewrite it here too, TLS block included. Left unpatched, this rule serves a host nobody
|
|
# visits and uploads quietly fall back to the /api/ rule — where every upload between 4 and 13 MB
|
|
# meets the controller's HTML 413 instead of Jarvis's own answer, and small files keep working, so
|
|
# nothing looks broken until somebody attaches a large one.
|
|
apiVersion: networking.k8s.io/v1
|
|
kind: Ingress
|
|
metadata:
|
|
name: jarvis-uploads
|
|
namespace: jarvis
|
|
annotations:
|
|
# With the main Ingress, for the same reason: last, once the Services have endpoints.
|
|
argocd.argoproj.io/sync-wave: "2"
|
|
# 13376k is 13 MiB and 64 KiB: exactly the most the API itself reads on this path — a workspace
|
|
# image of up to 10 MiB, the copy of it prepared for the model (at most 3 MiB), and 64 KiB for
|
|
# the multipart framing and the name (`UploadGate.BodyMaxBytes(UploadRoute.Documents)` +
|
|
# `UploadGate.MultipartOverhead`, in src/Jarvis.Api/Files/UploadEndpoint.cs; both refuse
|
|
# strictly above). Not less: a body the API would take would meet this ceiling first, and the
|
|
# controller's answer is an HTML page the client cannot translate. Not more: the API refuses
|
|
# anything larger unread. A composer attachment over 10 MiB still gets through here, and meets
|
|
# the API's own JSON 413.
|
|
nginx.ingress.kubernetes.io/proxy-body-size: "13376k"
|
|
# Everything the API does with a file happens before it answers: a wait for an upload slot, a
|
|
# PDF's text extraction (capped at 20s), a 13 MB row write. Two minutes is headroom over that,
|
|
# and far below the hour the main Ingress keeps open for idle websockets, which have no business
|
|
# on this path.
|
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "120"
|
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "120"
|
|
# Request buffering is left at the controller's default, ON: the controller reads the whole body
|
|
# before it opens a connection to the api, so a slow client costs the controller's disk rather
|
|
# than one of the api pod's few upload slots and the memory behind it.
|
|
#
|
|
# And no `custom-http-errors` override. A controller that sets it replaces the body of the
|
|
# statuses it lists, and every refusal the api makes on this path is a 4xx — busy included,
|
|
# which is a 429, never a 503. The one 4xx such lists usually name, 404, is a status whose body
|
|
# the client never reads.
|
|
spec:
|
|
ingressClassName: nginx
|
|
tls:
|
|
- hosts: ["jarvis.example.com"]
|
|
secretName: jarvis-tls
|
|
rules:
|
|
- host: jarvis.example.com
|
|
http:
|
|
paths:
|
|
- path: /api/uploads/
|
|
pathType: Prefix
|
|
backend:
|
|
service:
|
|
name: jarvis-api
|
|
port:
|
|
name: http
|