No per-service fees - one plan, unlimited appsFree tier available - start building today15% off your workspace - subscribe to our blogNo per-service fees - one plan, unlimited appsFree tier available - start building today15% off your workspace - subscribe to our blog
Miget x AIPlansEnterpriseCompareBlogDashboard
Start for Free
Blog/Docker/Containers/
·

Immich on Docker Compose: The Requirements Nobody Mentions

Immich is a self-hosted photo and video library: you point your phone at it, it backs everything up, and it gives you search, faces, albums and a timeline without any of it leaving your server. It is the most credible open-source answer to Google Photos, and it deploys with Docker Compose.

The compose file is easy. What trips people up is that Immich has real hardware requirements, an unusual database, and one storage rule that happens to contradict what most self-hosters instinctively do. This post covers the compose file and the four constraints behind it. Disclosure: we maintain this as an open-source template in our stack catalogue, but the compose file below is vanilla and runs anywhere.

The compose file

services:
  immich-server:
    image: ghcr.io/immich-app/immich-server:v2.7.5
    restart: unless-stopped
    environment:
      DB_HOSTNAME: database
      DB_USERNAME: immich
      DB_PASSWORD: ${DB_PASSWORD:?Database password}
      DB_DATABASE_NAME: immich
      REDIS_HOSTNAME: redis
    ports:
      - "2283:2283"
    depends_on:
      - database
      - redis
    volumes:
      - library:/data

  immich-machine-learning:
    image: ghcr.io/immich-app/immich-machine-learning:v2.7.5
    restart: unless-stopped
    volumes:
      - model-cache:/cache

  database:
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
    restart: unless-stopped
    environment:
      POSTGRES_USER: immich
      POSTGRES_PASSWORD: ${DB_PASSWORD:?Database password}
      POSTGRES_DB: immich
      PGDATA: /var/lib/postgresql/data/pgdata
      POSTGRES_INITDB_ARGS: '--data-checksums'
    volumes:
      - dbdata:/var/lib/postgresql/data

  redis:
    image: valkey/valkey:8-alpine
    restart: unless-stopped

volumes:
  library:
  model-cache:
  dbdata:

Four services, three volumes. Now the parts that decide whether this works.

1. It needs 6 GB of RAM, and one container is most of it

Immich's own requirements page is specific: "Minimum 6GB, recommended 8GB" for RAM, and "Minimum 2 cores, recommended 4 cores" for CPU.

That is more than people expect from a photo app, and the reason is the machine-learning container. It runs the models behind smart search and face recognition, and it is by far the largest consumer in the stack. A working split looks roughly like this:

ServiceRAM
immich-machine-learning3 GB
immich-server2 GB
database1 to 2 GB
redis256 MB

If you have a 4 GB machine, the docs give you an out: "For systems with only 4GB of RAM, Immich can be run with machine learning features disabled." In practice that means not running the immich-machine-learning service and turning the features that depend on it off in the admin settings. There is no environment variable that switches machine learning off from the server side, so removing the container is the mechanism. You lose smart search and face grouping. You keep upload, albums, timeline, sharing and mobile backup, which is most of why people install it.

One more CPU detail worth checking before you plan an upgrade: on amd64, the machine-learning container requires the x86-64-v2 microarchitecture level or newer. Version 2.7.5 is the last release that supports x86-64-v1, so older hardware pins you to that version.

2. The database is not Postgres, exactly

Look at that image name again:

ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0

That is Postgres with vector extensions compiled in. Immich stores embeddings for smart search and face recognition and queries them by similarity, which stock Postgres cannot do.

The practical consequence catches people who are trying to be tidy: you cannot point Immich at a generic managed Postgres. Not the one your provider offers, not the postgres:16 container you already run for three other apps. It needs this image, or another build carrying the same extensions at compatible versions. DB_VECTOR_EXTENSION exists to select between them, but the extension has to be there in the first place.

Treat the database image as part of the application, not as interchangeable infrastructure.

3. Never put the database on a network share

This is the one that costs people their library, and it is worth quoting directly. Immich's requirements say the database "should ideally use local SSD storage, and never a network share of any kind."

The reason it needs saying is that Immich's audience is the NAS audience. The instinct is to put everything on the array: photos, database, all of it, because that is where the storage is. Photos on the NAS is fine and expected. The Postgres data directory on an SMB or NFS mount is not, and the failure mode is not a clean error at startup. It is corruption later.

The related rule is filesystem support: the docs call for a "Unix-compatible filesystem (EXT4, ZFS, APFS, etc.) with support for user/group ownership and permissions", and state the database "will not work on any filesystem formatted in NTFS or ex/FAT/32", nor in WSL against a mounted host directory.

So: library on the big storage, database on local SSD. Two different volumes with two different rules, which is why the compose file above keeps them separate.

4. The port is 2283

IMMICH_PORT defaults to 2283 for the server, and 3003 for the machine-learning service. That is an unusual number and it matters in two places: your reverse proxy config, and any platform that expects an application to listen on a fixed port.

On Miget, HTTP is always served from port 5000, so the template sets IMMICH_PORT: "5000" rather than changing anything else. On a plain VPS behind nginx or Caddy you leave the default and proxy to 2283.

What it costs to store

Two numbers to plan around.

Your library is your originals plus what Immich generates. The docs put that overhead at "10-20% on average" for thumbnails and transcoded video. So 500 GB of photos and video wants somewhere around 550 to 600 GB of volume, before you account for growth.

The machine-learning model cache is separate and small by comparison, in the low gigabytes, but it is a real volume and it should persist. If you throw it away on every restart, the models are downloaded again.

The honest framing on cost: Immich replaces a subscription that scales with how many photos you have, with a machine that costs the same whether you upload one photo a month or ten thousand. Whether that is cheaper depends entirely on your library size and whether you were going to pay for the machine anyway. Where it clearly wins is control, and where it clearly costs you is that backups are now your job. A photo library is exactly the kind of data where "I thought it was backed up" is discovered too late, so decide on that before you migrate anything off a service that was doing it for you.

Frequently asked questions

How much RAM does Immich need?

Six gigabytes minimum and eight recommended, per Immich's own requirements. The machine-learning container is most of that. On a 4 GB machine you can run without it, which costs you smart search and face recognition but leaves upload, albums, timeline and mobile backup working.

Can I use my existing PostgreSQL for Immich?

Only if it has the vector extensions Immich needs. The official image is Postgres with vectorchord and pgvectors built in, because smart search and face recognition are similarity queries over embeddings. A stock postgres:16 container or a generic managed Postgres will not work.

Can I store the Immich database on my NAS?

No. The documentation is explicit that the database should use local SSD storage and never a network share of any kind. Photos on network storage are fine and expected. The Postgres data directory on NFS or SMB risks corruption, and it will not announce itself at startup.

What port does Immich run on?

2283 by default for the server, and 3003 for the machine-learning service. Set IMMICH_PORT if your platform requires a specific one, and point your reverse proxy at whichever you settle on.

How much disk space will Immich use?

Your originals plus 10 to 20 percent on average for generated thumbnails and transcoded video. Budget the model cache separately, in the low gigabytes, and keep it on a persistent volume so the models are not re-downloaded on every restart.

Is Immich production ready?

It is stable enough that people run their only copy of their photos on it, which is a decision worth making deliberately rather than by default. It still ships breaking changes between versions, so pin the image tag rather than tracking latest, read the release notes before upgrading, and back the database up before you do.

Immich Docker Compose: A Setup That Survives Contact