Immich is one of those apps that runs perfectly on localhost:2283 and then falls apart the moment you put it behind a reverse proxy. The symptoms are specific and repeatable: uploading a video fails at a certain size, the timeline won't live-update, the mobile app can't log in, or Immich keeps generating links to the wrong host. None of these are reverse-proxy bugs in general — they're the handful of things Immich in particular needs the proxy to get right. The generic guidance in reverse proxy at the edge vs end-to-end TLS still applies; this is the Immich-specific layer on top.
Edge case 1: large uploads rejected
Phone videos are big, and proxies cap request bodies by default. nginx returns 413 Request Entity Too Large at 1 MB until you raise it:
client_max_body_size 50000M;
On Traefik there's no body cap by default, but if you've set maxRequestBodyBytes anywhere, raise it. This single setting is the most common "Immich uploads fail" cause.
Edge case 2: WebSockets and the live timeline
Immich uses WebSockets for live updates and job status. A proxy that doesn't forward the Upgrade/Connection headers leaves the UI looking frozen. For nginx:
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Traefik handles WebSocket upgrades automatically, so if live updates fail there, suspect a timeout cutting the long-lived connection rather than the upgrade itself.
Edge case 3: timeouts on long operations
Thumbnail generation, large uploads, and ML jobs hold connections open. A 60-second proxy read timeout cuts them off mid-flight. Raise proxy_read_timeout/proxy_send_timeout on the Immich route specifically — not globally — the same targeted-timeout principle that self-hosted AI apps need.
Edge case 4: Immich thinks it's on the wrong URL
Immich builds share links and redirects from the host it believes it's serving. Behind a proxy that means forwarding the real host and scheme:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $remote_addr;
Miss X-Forwarded-Proto and Immich generates http:// links on an HTTPS site — mixed-content failures and broken shares.
Edge case 5: TLS and certificate renewal
Immich over HTTPS is table stakes, but a cert that silently fails to renew breaks the mobile app days later with a confusing error. Make sure renewal actually reloads the proxy — the exact trap in Let's Encrypt renew-and-reload behind a Docker proxy.
The full Immich proxy checklist
-
client_max_body_sizeraised well above your largest video. - WebSocket upgrade headers forwarded.
- Read/send timeouts raised on the Immich route only.
-
Host+X-Forwarded-Protoforwarded so links use the right URL. - HTTPS with renewal that reloads the proxy.
Skip the hand-wiring
Every edge case above is a setting that a managed deployment can set for you. Bringing Immich up from a template wires the proxy, TLS, and headers together instead of leaving you to rediscover client_max_body_size at 2am.
Deploying Immich with its reverse proxy and TLS configured together in ServerCompass — the edge cases above are handled before the first upload.
Get these five settings right and Immich behind a proxy is rock solid. Get any one wrong and you'll chase a different confusing symptom for each.
From across the StoicSoft network
Hand-curated reads on the same topic from sister sites in the StoicSoft family.
Deploy Handbook8 min readBest single-dashboard app health for self-hosters who aren't ready for Prometheus
Homelab and VPS users want one calm dashboard for app health — not a full observability stack. Here are the tools that hit the middle layer between SSH and Grafana.
Read on deployhandbook.com- Deploy Handbook8 min read
EU-Based Cloudflare Alternatives: Reverse Proxy, SSL Termination, and No-Ingress Edge Security
EU teams asking for a Cloudflare alternative usually want edge security under EU jurisdiction. A grouped comparison of EU CDNs, self-hosted EU edges, and no-ingress tunnels — and how to choose.
Read on deployhandbook.com
