Sync the self-hosting stack
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
# One hostname, two backends.
|
||||
#
|
||||
# The API is routed STRAIGHT AT ITS SERVICE rather than through the web container's nginx, which is
|
||||
# what that nginx does on Compose. Two reasons: it removes a hop from every API request and every
|
||||
# websocket frame, and it makes the web pod a pure static server again — no dependency on resolving
|
||||
# the API, nothing to keep in sync between an ingress and a config file.
|
||||
#
|
||||
# The consequence has to be applied, not just noted: there is now exactly ONE proxy rewriting
|
||||
# X-Forwarded-For, so `TRUST_PROXY_HOPS` is 1. It is 2 in the compose files, and leaving it there
|
||||
# would make `req.ip` a value the caller chooses. See 02-config.yaml.
|
||||
#
|
||||
# Set `externalTrafficPolicy: Local` on the ingress controller's own Service as well, or the node's
|
||||
# SNAT will make every request in the world appear to come from a handful of addresses — which
|
||||
# defeats every per-address limit in the application at once.
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: jarvis
|
||||
namespace: jarvis
|
||||
annotations:
|
||||
# An agent is idle between operations and the server pings every 30s, so this only has to
|
||||
# outlast a quiet period comfortably. Too short and a healthy fleet reconnects all day.
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
||||
# Matches BODY_LIMIT in apps/api/src/main.ts. A document may hold 400,000 characters, which is
|
||||
# over a megabyte once accented text is UTF-8 encoded, and a diagram export posts back the SVG
|
||||
# the browser rendered. Below this they are rejected as a bare 413 with no message.
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "4m"
|
||||
#
|
||||
# NO affinity annotation, and none should be added. The reflex is understandable — there are
|
||||
# websockets here — but stickiness cannot solve the problem it would be hired for: the hard case
|
||||
# is co-locating an operator's browser with an AGENT's websocket, which arrives from a different
|
||||
# network at a different time and whose id is not even known at the browser's handshake. No
|
||||
# ingress annotation can express that; it is handled in the application, over Redis.
|
||||
#
|
||||
# And there is no polling to make sticky: both the client and the server pin
|
||||
# transports: ["websocket"], so one logical socket is one TCP connection.
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts: ["jarvis.example.com"]
|
||||
secretName: jarvis-tls
|
||||
rules:
|
||||
- host: jarvis.example.com
|
||||
http:
|
||||
paths:
|
||||
# Longest prefix first for readers; the controller sorts by specificity itself.
|
||||
#
|
||||
# The agent websocket has its own rule even though it sits under /api/, mirroring the
|
||||
# split in apps/web/nginx.conf: it is the one path where an idle connection legitimately
|
||||
# stays open for an hour between frames.
|
||||
- path: /api/agents/ws
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: jarvis-api
|
||||
port:
|
||||
name: http
|
||||
- path: /socket.io/
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: jarvis-api
|
||||
port:
|
||||
name: http
|
||||
- path: /api/
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: jarvis-api
|
||||
port:
|
||||
name: http
|
||||
# Everything else is the SPA, whose nginx answers index.html for any path it does not
|
||||
# have a file for.
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: jarvis-web
|
||||
port:
|
||||
name: http
|
||||
Reference in New Issue
Block a user