Back to Article List

What to do when the Immich web UI is not working

What to do when the Immich web UI is not working - What to do when the Immich web UI is not working

The Immich web UI not working presents a dozen ways (connection refused, a blank white page, an endless spinner, a 502 from your proxy) and every one of them is the same short story: somewhere between your browser and the immich-server container, one layer is down. There are only five layers. Check them in order and the culprit has nowhere to hide, usually inside ten minutes.

Layer 1: Check container status

SSH to the server and ask Docker directly:

cd /opt/immich && docker compose ps

You want every service up and immich-server specifically showing healthy. The failure signatures read like a menu. A container restarting in a loop: read its logs (next layer). Postgres unhealthy: the app can't start without it, and the classic causes are a special character in DB_PASSWORD or a corrupted shutdown. Everything missing entirely: the stack never started, docker compose up -d and watch. A server that rebooted without the containers coming back means restart policies got stripped from a hand-edited compose file; the official file sets them, one more argument for keeping it stock, as covered in the install guide.

Layer 2: Read the server logs

docker compose logs --tail=100 immich-server

Immich's startup logs are talkative and honest. Database connection refusals, migration failures after an update, permission errors on UPLOAD_LOCATION, a port already taken: each announces itself in plain text within the first screen. Two patterns worth translating. Endless "waiting for database" means Postgres is the patient to treat, not the server container. And migration errors immediately after an update mean the release notes you skipped had a step in them; the update guide's routine exists for exactly that morning.

Layer 3: Test port 2283

Containers healthy, logs clean, page still dead: test the port from the server itself.

curl -I http://localhost:2283

An HTTP response back means Immich is fine and your problem lives further out (keep going). Refused means the port mapping is off, check the compose file's ports section against what you're browsing to. From your own machine, the same curl against the server's IP splits it further: works locally but not remotely is a firewall or security-group story, the usual suspects being ufw and the VPS provider's cloud firewall both needing the port (or better, only your proxy's ports) open. The full port layout and what should face the internet is the Immich ports guide's territory.

Layer 4: Reverse proxy and certificates

Direct IP-and-port works, the nice domain doesn't: your reverse proxy is the layer. A 502 there means the proxy can't reach the backend (wrong upstream address, or the containers restarted onto a new Docker network IP, which pointing the proxy at a container name instead of an IP prevents permanently). A page that loads but hangs on a spinner with console errors about websockets means the proxy lacks the upgrade headers Immich needs; the known-good config blocks in the reverse proxy section of our error loading image guide fix the same disease here, because it's the same disease. Certificate expiry rounds out the set, browsers increasingly refuse rather than warn, so an expired cert reads as "site down" to the family.

Layer 5: Browser cache and app version mismatch

The endgame layer collects the odd cases. A blank white page with everything else healthy is often a stale service worker from a previous version; hard-refresh (Ctrl+F5), then try a private window, and if private works, clear site data for the domain and the regular window heals. Aggressive content blockers occasionally eat the UI's requests, a private-window test convicts those too. And when the web UI works but the mobile app refuses: check versions. Immich's server and apps track each other, and a phone app several majors adrift shows connection errors that look like server failure; the compatibility rule (apps support current and prior major, servers only their own) lives in the update guide.

The five-command checklist

Bookmark-worthy summary of the whole ladder: docker compose ps, then logs, then curl localhost:2283, then bypass the proxy, then a private browser window. Each step either works (culprit is further out) or fails (culprit found), so five commands corner it every time. Chronic instability rather than one bad morning usually means the machine is too small for the library indexing on it (the ML container OOM-killing its neighbors shows up as random unavailability); free -h during an indexing run tells that story, and the fix is memory, not config.

Our Immich VPS tiers are sized with that headroom in mind, since the difference between "sometimes down" and "boring" is usually one RAM step.

Never delete a memory again

Keep every photo and video of the people you love, on reliable storage with unmetered bandwidth and a cost that stays predictable as the years add up.
Billing Cycle

VPS.H1

£5.13 Save  14 %
£4.39 Monthly
  • 1 vCPU AMD EPYC
  • 2 GB RAMMEMORY
  • 750 GB HDDSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

VPS.H3

£18.33 Save  20 %
£14.66 Monthly
  • 4 vCPU AMD EPYC
  • 8 GB RAMMEMORY
  • 2500 GB HDDSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

VPS.H4

£26.77 Save  18 %
£22.00 Monthly
  • 6 vCPU AMD EPYC
  • 12 GB RAMMEMORY
  • 3500 GB HDDSTORAGE
  • Unmetered bandwidth
  • IPv4 & IPv6IPv6 is currently unavailable in France, Finland or the Netherlands. included

Q & A

Immich worked yesterday and nothing changed. What broke?

Something changed anyway; the usual invisible movers are disk filling past full, an unattended system update restarting Docker, a certificate expiring or the VPS rebooting without container restart policies. The five layers find which one in minutes.