Immich is a high-performance, self-hosted photo and video management solution. Think of it as your own private Google Photos — complete with automatic mobile uploads, facial recognition, powerful search, and album organization.
In this guide, I’ll show you how to deploy Immich using Docker Compose on your own server or home lab setup.
If you prefer a graphical interface to manage your Docker containers and stacks, you can use Portainer. Visit this link to learn how to install Portainer and simplify container management.
Docker Compose File for Immich
Below is the docker-compose.yml file you can use to deploy Immich. It defines the core services: the Immich server, machine learning engine, Redis, and PostgreSQL with the required vector extension for search functionality.
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- stack.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:
- stack.env
restart: always
healthcheck:
disable: false
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm@sha256:42cba146593a5ea9a622002c1b7cba5da7be248650cbb64ecb9c6c33d29794b1
healthcheck:
test: redis-cli ping || exit 1
restart: always
database:
container_name: immich_postgres
image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:739cdd626151ff1f796dc95a6591b55a714f341c737e27f045019ceabf8e8c52
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
healthcheck:
test: >-
pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1; Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; echo "checksum failure count is $$Chksum"; [ "$$Chksum" = '0' ] || exit 1
interval: 5m
start_interval: 30s
start_period: 5m
command: >-
postgres -c shared_preload_libraries=vectors.so -c 'search_path="$$user", public, vectors' -c logging_collector=on -c max_wal_size=2GB -c shared_buffers=512MB -c wal_compression=on
restart: always
volumes:
model-cache:
Environment Variables
Make sure you define the following environment variables before running the stack:
UPLOAD_LOCATION=/opt/immich/data
DB_DATA_LOCATION=/opt/immich/db
TZ=Europe/Berlin
IMMICH_VERSION=release
DB_PASSWORD=<Secure Password>
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
Final Thoughts
With this setup, you can enjoy full control over your photo and video library, complete with privacy, advanced features, and the flexibility of open source.
If you’re running this on a home server or in a homelab, you’ll appreciate how easy it is to scale and customize. Happy self-hosting!
