Ditch Google Photos – Self-Host your Photos with Immich

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!

Video walk-through

Leave a Reply

Your email address will not be published. Required fields are marked *