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 and make sure docker compose version prints v2.
Create a working directory:
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:
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:
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 instead of retyping it, because the official file also pins image digests.
Step 3: Start and open the app
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 installed on the host, this is the whole config:
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:
docker compose pull && docker compose up -d
Troubleshooting
- Server keeps restarting after an upgrade: you are probably running an old
docker-compose.ymlagainst 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_LOCATIONto 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.
Spotted something out of date? Tell us and we will update the guide.