# How to self-host Immich with Docker Compose

> Deploy Immich on any VPS or home server in 15 minutes: the official Docker Compose stack, .env settings, HTTPS reverse proxy, backups and safe upgrades.

## Key facts

| Fact | Value |
|---|---|
| App | Immich (https://appsgit.com/apps/immich) |
| Difficulty | beginner |
| Time | about 15 minutes |
| Requirements | 2 vCPU / 4 GB RAM minimum (6 GB+ recommended); Docker + Docker Compose v2; Disk space for your photo library on local storage; A domain name (optional, for HTTPS) |
| Last updated | 2026-10-06 |

## What is Immich?

Immich is a self-hosted photo and video backup platform that works as a private alternative to Google Photos and iCloud Photos. It is open source under the AGPL-3.0 license, has native mobile apps that back up your camera roll automatically, and includes face recognition, map view, shared albums and natural-language search. It is one of the most actively developed self-hosted projects on GitHub.

## Requirements

- A Linux server with at least 2 CPU cores and 4 GB of RAM (6 GB or more if you keep machine learning enabled).
- Docker Engine and Docker Compose v2.
- Local disk (SSD preferred) for the Postgres database, plus as much storage as your library needs.
- A domain name pointing at the server if you want HTTPS access from your phone outside the house.

## Step 1: Prepare the server

This guide assumes Ubuntu 24.04 with Docker already installed. If you still need Docker, follow the official [Docker Engine install guide for Ubuntu](https://docs.docker.com/engine/install/ubuntu/) and make sure `docker compose version` prints v2.

Create a working directory:

```bash
mkdir -p ~/immich && cd ~/immich
```

## Step 2: Create the Docker Compose file

Immich ships its Compose file with every release, and the project warns that the file on the `main` branch may not match the latest release. The stack has four services: the server, the machine learning worker, Valkey (a Redis-compatible cache) and a custom Postgres image that bundles the VectorChord and pgvecto.rs extensions used for smart search.

Save this as `docker-compose.yml`:

```yaml
name: immich

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    volumes:
      - ${UPLOAD_LOCATION}:/data
      - /etc/localtime:/etc/localtime:ro
    env_file:
      - .env
    ports:
      - "2283:2283"
    depends_on:
      - redis
      - database
    restart: always
    healthcheck:
      disable: false

  immich-machine-learning:
    container_name: immich_machine_learning
    image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:9
    healthcheck:
      test: redis-cli ping | grep -q PONG || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: "--data-checksums"
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    shm_size: 128mb
    restart: always
    healthcheck:
      disable: false

volumes:
  model-cache:
```

Then create `.env` next to it:

```bash
UPLOAD_LOCATION=./library
DB_DATA_LOCATION=./postgres
TZ=Etc/UTC
IMMICH_VERSION=v3
DB_PASSWORD=CHANGE_ME
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
```

Replace `CHANGE_ME` with a random value. Immich asks for letters and digits only in the database password, so a hex string is ideal: run `openssl rand -hex 32` and paste the output. Pinning `IMMICH_VERSION` to a major version (`v3`) means you only move to the next major release when you choose to. For the most reproducible setup, download the exact file from the [latest release](https://github.com/immich-app/immich/releases/latest) instead of retyping it, because the official file also pins image digests.

## Step 3: Start and open the app

```bash
docker compose up -d
docker compose ps
```

The first start downloads several gigabytes of images and machine learning models, so give it a few minutes. Then open `http://YOUR_SERVER_IP:2283`. The first account you create becomes the administrator. Install the Immich app on your phone, enter the server URL, sign in, and enable background backup.

## Step 4: Put it behind HTTPS

The mobile apps work best over HTTPS on a real domain. With [Caddy](https://caddyserver.com/docs/) installed on the host, this is the whole config:

```caddyfile
photos.example.com {
    reverse_proxy 127.0.0.1:2283
}
```

Caddy fetches a Let's Encrypt certificate automatically. Immich uploads can be large, and Caddy has no body size limit by default. If you use Nginx Proxy Manager instead, raise `client_max_body_size` and enable WebSocket support. Once HTTPS works, change the port mapping to `"127.0.0.1:2283:2283"` so the plain HTTP port is no longer reachable from the internet. Docker-published ports bypass `ufw`.

## Backups and upgrades

Back up two things: the `UPLOAD_LOCATION` folder (your originals, thumbnails and encoded videos) and the database. Immich creates automatic database dumps inside `UPLOAD_LOCATION/backups`, so copying the whole library folder off-site with a tool like restic or Borg covers both. Never copy the raw `postgres` folder while the container is running.

To upgrade, read the release notes first (Immich occasionally has breaking changes), then run:

```bash
docker compose pull && docker compose up -d
```

## Troubleshooting

- **Server keeps restarting after an upgrade:** you are probably running an old `docker-compose.yml` against a new image. Download the Compose file from the matching release and compare.
- **Face recognition or smart search never finishes:** the machine learning container may be out of memory. Check `docker compose logs immich-machine-learning`, and add RAM or swap.
- **Uploads fail through the reverse proxy:** raise the proxy's upload size limit and timeouts. Large videos can exceed common defaults.
- **Database errors on a NAS:** move `DB_DATA_LOCATION` to local disk. Network shares are not supported for Postgres.

## Next steps

Set up external libraries to index existing photo folders without copying them, enable the storage template to control folder naming, and create user accounts for your family. If you have a supported GPU, add the hardware acceleration Compose files for faster transcoding and machine learning.

## FAQ

### What port does Immich use?

The Immich server listens on port 2283. The mobile apps and the web UI both connect to that port, or to your HTTPS domain once you put a reverse proxy in front of it.

### Is Immich free?

Yes. Immich is free and open source under the AGPL-3.0 license. There is an optional paid supporter license that unlocks nothing; it only funds development.

### How much RAM does Immich need?

The project recommends at least 4 GB, and 6 GB or more for comfortable machine learning (face recognition and smart search). On small servers you can disable the machine learning container to save memory.

### Does Immich need a GPU?

No. The default Compose file runs transcoding and machine learning on the CPU. Hardware acceleration for NVIDIA, Intel, AMD and some ARM boards is optional and enabled through extra Compose files.

### Immich vs PhotoPrism: which should I choose?

Immich is closer to a Google Photos replacement, with native iOS and Android apps and automatic phone backup. PhotoPrism focuses on browsing, tagging and organising an existing library through the browser.

### Can I store the Immich database on a NAS share?

No. The Postgres data directory must be on local storage, because network shares are not supported for the database. The photo library itself can live on a NAS mount.

Prefer not to do it yourself? [appsgit installation help](https://appsgit.com/services/install) installs it on your server for a fixed quote.

---

Canonical page: https://appsgit.com/guides/immich
Source: appsgit (https://appsgit.com), the app store for github. Data from the GitHub API, refreshed nightly.
Machine access: JSON API https://appsgit.com/api/v1/apps (OpenAPI: https://appsgit.com/openapi.json), MCP server https://mcp.appsgit.com/mcp, full index https://appsgit.com/llms-full.txt.
