Back to Article List

Immich ports and what to open on a public server

Immich ports and what to open on a public server

Immich's networking is refreshingly small: one port faces you, everything else stays inside Docker's network. That hasn't stopped the confusion, partly because the default changed over the project's history and old guides still teach it wrong. Current state of the world: the Immich default port is 2283, and here's what listens where, how to change it and what a proper public setup exposes instead (spoiler: not 2283).

Default ports for each Immich container

A stock Immich stack runs four services, and their listening situation looks like this:

  • immich-server: 2283, the only published port. Web UI, API and mobile app traffic all arrive here; there's no separate API port to configure, which keeps client setup honest.
  • immich-machine-learning: 3003, internal only. The server calls it across the Docker network; nothing outside the host should ever see it.
  • Postgres: 5432, internal only, deliberately unpublished. Your photos' metadata lives here and the official compose file correctly keeps it off the network.
  • The Redis-compatible cache: 6379, internal only, same story.

Historical footnote that still generates confusion: older Immich versions mapped host 2283 to container 3001, so ancient guides and compose files reference 3001 everywhere. Modern releases listen on 2283 inside and out, and if you're carrying a years-old compose file with the 3001 mapping, that's one more nudge toward re-downloading the current official file during your next Immich update.

Change the Immich port

Two clean options. The compose mapping is the usual one; in docker-compose.yml under the immich-server service:

ports:
  - "8080:2283"

Left side is the host port you want, right side stays 2283. Alternatively the .env variable IMMICH_PORT adjusts the published port without touching the compose file on current releases. Either way, every client that stored the old address (each family phone, browser bookmarks) needs the new port typed in; the apps don't discover changes, they just fail politely.

What not to do: publish Postgres or the ML port to "check something". The database holds every face, location and album on your server, and exposed Postgres instances get found by scanners in hours. Anything you'd want to inspect is reachable with docker compose exec from the host, no published port required.

Firewalling: LAN server versus VPS

On a home LAN box, allow 2283 from your subnet and you're done; nothing else needs opening because nothing else is published. On a VPS the calculus changes, since every open port faces the whole internet. The arrangement that holds up: 2283 closed to the world, reachable only from localhost where a reverse proxy picks it up, with 80 and 443 as the public face. Both the OS firewall and the provider's cloud firewall should agree on that (our panel firewall on Immich VPS plans is where the second half of that rule lives). The result: your phone talks HTTPS on 443 like it's any other website, and port 2283 becomes an implementation detail.

Reverse proxy configuration for Immich

Immich behind a proxy has two needs beyond vanilla forwarding, and missing them produces the classic "uploads fail at exactly 1 MB" and "timeline never live-updates" bugs. Body size limits must be huge (phone videos run to gigabytes) and websocket upgrade headers must be present. Caddy handles both with almost nothing:

photos.example.com {
    reverse_proxy 127.0.0.1:2283
}

Caddy does websockets and sane limits by default plus automatic HTTPS, which is why it's my recommendation for self-hosters who don't already run Nginx. The Nginx version needs the explicit lines (client_max_body_size, proxy_read_timeout, the Upgrade/Connection headers), all listed in Immich's reverse proxy docs as copy-paste blocks; our Nginx reverse proxy walkthrough covers the surrounding setup if that layer is new to you. Once the proxy answers on the domain, point the mobile apps at https://photos.example.com with no port at all, and enjoy retiring the :2283 from every conversation with relatives.

Verify ports and firewall rules

Three probes confirm the whole design. From the server, curl -I http://localhost:2283 answers (Immich alive). From outside, the same against your public IP and 2283 times out or refuses (firewall doing its job). And https://photos.example.com loads the login page (proxy path healthy). If probe one fails, it's the app, not the network, and the container-health ladder in our web UI troubleshooting guide takes over.

That trio, run in thirty seconds, distinguishes every port problem from every non-port problem, which is most of what a networking guide can promise you.

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.
Cycle de facturation

VPS.H1

$6.99 Save  14 %
$5.99 Mensuel
  • 1 vCPU AMD EPYC
  • 2 GB mémoire RAM
  • Stockage HDD
  • Bande passante illimitée
  • IPv4 & IPv6 inclus La prise en charge d’IPv6 n’est actuellement pas disponible en France ou aux Pays-Bas.
  • Gestion du pare-feu
  • Suivi serveur gratuit
  • KVM virtualisation

VPS.H3

$24.99 Save  20 %
$19.99 Mensuel
  • 4 vCPU AMD EPYC
  • 8 GB mémoire RAM
  • Stockage HDD
  • Bande passante illimitée
  • IPv4 & IPv6 inclus La prise en charge d’IPv6 n’est actuellement pas disponible en France ou aux Pays-Bas.
  • Gestion du pare-feu
  • Suivi serveur gratuit
  • KVM virtualisation

VPS.H4

$36.49 Save  18 %
$29.99 Mensuel
  • 6 vCPU AMD EPYC
  • 12 GB mémoire RAM
  • Stockage HDD
  • Bande passante illimitée
  • IPv4 & IPv6 inclus La prise en charge d’IPv6 n’est actuellement pas disponible en France ou aux Pays-Bas.
  • Gestion du pare-feu
  • Suivi serveur gratuit
  • KVM virtualisation

FAQ

Can I run Immich on port 443 directly without a proxy?

The app itself speaks plain HTTP and doesn't terminate TLS, so no, something has to hold the certificate. That something can be as small as the two-line Caddy block, which is less config than teaching anything else to do HTTPS.