1
S3 storage
Set up the three buckets and two users as described in S3, with your S3 service or with Garage in the cluster, and put the four keys into the Secret
overleaf-s3. The configuration below uses the Garage example from that page.2
Configuration
This ConfigMap replaces
30-config.yaml. It adds S3 and git-bridge and points OVERLEAF_SITE_URL at the load balancer:60-config.yaml
3
Replicas
70-overleaf.yaml
- StatefulSet, not Deployment. Each replica gets a stable name (
overleaf-0,overleaf-1, …) that the load balancer cookie and git-bridge refer to, andOrderedReadystartsoverleaf-0alone first, so only one replica runs the database migrations. - One replica per node. Each replica starts its compiles through its node’s Docker and keeps them in its node’s
/srv/overleaf-ha. V1_HISTORY_URLper replica. Each replica hands out history links with its own name, so that git-bridge can reach them.
4
git-bridge
75-git-bridge.yaml
GIT_BRIDGE_HOST is a fixed IP address.5
Load balancer
The HAProxy configuration is Overleaf’s sample with five changes:
/project/<id>/mcp routed to overleaf-0 like /git/ (see MCP Server), plain HTTP on port 8080 (the image runs as a non-root user, which cannot bind port 80 under containerd), servers found through cluster DNS (pod IPs change on every restart), a DaemonSet so that every node answers, and balance leastconn instead of the default roundrobin (see the Q&A below).80-haproxy.yaml
externalTrafficPolicy: Local keeps the users’ IP addresses in X-Forwarded-For.6
TLS
Terminate HTTPS in HAProxy as described in TLS proxy, then set
OVERLEAF_SITE_URL to the https:// address and OVERLEAF_SECURE_COOKIE: "true" in 60-config.yaml.What to expect
We tested three replicas on three nodes with 2 vCPUs and 4 GB each, with MongoDB, Redis, Garage, git-bridge and HAProxy on the same nodes:- 12 users compiling a 600-page document at the same time: all 12 compiled and fetched their PDF, 4 users per replica; a round took 8 to 18 seconds. Each node kept at least 1.3 GB of memory available.
- Every user stays on one replica (cookie
server-pro-ha), including the PDF download that must come from the replica that compiled it. The same holds over HTTPS, including the editor’s WebSocket. - When a replica stops, its users get errors for about 15 to 20 seconds, until HAProxy marks it down; then they move to another replica and stay logged in, because sessions live in Redis.
Q&A
Why balance leastconn?
Why balance leastconn?
Answer: With Overleaf’s sample (
roundrobin, one HAProxy per node), 12 new users ended up 8, 3 and 1 on the three replicas in our test, and the busiest replica made the slowest users wait 29 seconds. With leastconn, which prefers the replica with the fewest open connections (each editor keeps a WebSocket open), the same test gave 4, 4 and 4 and 18 seconds. Stickiness is unchanged: it comes from the cookie.Can I use my ingress controller instead of HAProxy?
Can I use my ingress controller instead of HAProxy?
Answer: Yes, if it routes by a cookie to a stable replica, supports WebSockets, allows request times of 10 minutes and uploads of 50 MB, keeps its keep-alive timeout below 65 seconds, sends
X-Forwarded-For and X-Forwarded-Proto, and sends /git/ and /project/<id>/mcp to overleaf-0. Route to the replicas’ own names (overleaf-N.overleaf-hl), not to a Service that balances every request.How do I add a fourth replica?
How do I add a fourth replica?
Answer: Add a node with Docker and the TeX Live images, set
replicas: 4 in 70-overleaf.yaml, and add a server overleaf-3 ... line to the HAProxy configuration (and bump config-hash so HAProxy restarts).
