Как запустить сервис для работы с частным медиа?

Цель и необходимость

Корпорации манят бесплатным размещением наших медиа у себя на сервисах, но они же могут в одностороннем порядке изменить условия размещения, в том числе использовать частные медиа для обучения своих нейронных сетей. Лично для меня такая ситуация неприемлема, поэтому сначала составим требования к сервису для замены облачных сервисов:

  1. Хранение данных только на серверах, которые я контролирую.

  2. Поиск по медиа: люди, контекстный поиск, временной период, название, геокоординаты и т.д.

  3. Open-source код, который я могу посмотреть и изменить при необходимости.

В этой статье расскажу как можно запустить сервис Immich и настроить его под себя.

Установка Immich

# Создаем необходимые папки, файлы и запускаем контейнеры
curl -o- https://raw.githubusercontent.com/immich-app/immich/main/install.sh | bash

После скачивания образов и запуска должна быть ошибка, так как проект работает на базе моделей машинного обучения и требуются ресурсы видеокарты. Мои рабочие файлы для работы с видеокартой Nvidia выглядят как описано ниже. docker-compose.yml:

services:
  immich-server:
    container_name: immich_server
    image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
    extends:
      file: hwaccel.transcoding.yml
      service: nvenc 
    volumes:
      - ${UPLOAD_LOCATION}:/usr/src/app/upload
      - ${IMPORT_LOCATION}:/usr/src/app/import
    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}-cuda
    extends: 
      file: hwaccel.ml.yml
      service: cuda 
    volumes:
      - model-cache:/cache
    env_file:
      - .env
    restart: always
    healthcheck:
      disable: false

  redis:
    container_name: immich_redis
    image: docker.io/valkey/valkey:8-bookworm@sha256:a137a2b60aca1a75130022d6bb96af423fefae4eb55faf395732db3544803280
    healthcheck:
      test: redis-cli ping || exit 1
    restart: always

  database:
    container_name: immich_postgres
    image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:32324a2f41df5de9efe1af166b7008c3f55646f8d0e00d9550c16c9822366b4a
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_USER: ${DB_USERNAME}
      POSTGRES_DB: ${DB_DATABASE_NAME}
      POSTGRES_INITDB_ARGS: '--data-checksums'
      DB_STORAGE_TYPE: 'HDD'
    volumes:
      - ${DB_DATA_LOCATION}:/var/lib/postgresql/data
    shm_size: 128mb
    restart: always

volumes:
  model-cache:

hwaccel.ml.yml:

services:
  armnn:
    devices:
      - /dev/mali0:/dev/mali0
    volumes:
      - /lib/firmware/mali_csffw.bin:/lib/firmware/mali_csffw.bin:ro 
      - /usr/lib/libmali.so:/usr/lib/libmali.so:ro 
  
  rknn:
    security_opt:
      - systempaths=unconfined
      - apparmor=unconfined
    devices:
      - /dev/dri:/dev/dri

  cpu: {}

  cuda:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities:
                - gpu

  rocm:
    group_add:
      - video
    devices:
      - /dev/dri:/dev/dri
      - /dev/kfd:/dev/kfd

  openvino:
    device_cgroup_rules:
      - 'c 189:* rmw'
    devices:
      - /dev/dri:/dev/dri
    volumes:
      - /dev/bus/usb:/dev/bus/usb

  openvino-wsl:
    devices:
      - /dev/dri:/dev/dri
      - /dev/dxg:/dev/dxg
    volumes:
      - /dev/bus/usb:/dev/bus/usb
      - /usr/lib/wsl:/usr/lib/wsl

hwaccel.transcoding.yml:

services:
  cpu: {}

  nvenc:
    deploy:
      resources:
        reservations:
          devices:
            - driver: nvidia
              count: 1
              capabilities:
                - gpu
                - compute
                - video

  quicksync:
    devices:
      - /dev/dri:/dev/dri

  rkmpp:
    security_opt: 
      - systempaths=unconfined
      - apparmor=unconfined
    group_add:
      - video
    devices:
      - /dev/rga:/dev/rga
      - /dev/dri:/dev/dri
      - /dev/dma_heap:/dev/dma_heap
      - /dev/mpp_service:/dev/mpp_service
    volumes:
      - /etc/OpenCL:/etc/OpenCL:ro 
      - /usr/lib/aarch64-linux-gnu/libmali.so.1:/usr/lib/aarch64-linux-gnu/libmali.so.1:ro 
  vaapi:
    devices:
      - /dev/dri:/dev/dri

  vaapi-wsl:
    devices:
      - /dev/dri:/dev/dri
      - /dev/dxg:/dev/dxg
    volumes:
      - /usr/lib/wsl:/usr/lib/wsl
    environment:
      - LIBVA_DRIVER_NAME=d3d12

.env (подставляем свои значения):

UPLOAD_LOCATION=./library
IMPORT_LOCATION=<path>
DB_DATA_LOCATION=./config_postgres
IMMICH_VERSION=release
DB_PASSWORD=<password>
DB_USERNAME=<username>
DB_DATABASE_NAME=<name>
TZ=Europe/Moscow

После внесения этих правок сервисы запустились и в UI можно зайти через http://IP:2283. Создаем админскую учетную запись и настраиваем ее. Для вывода сервиса в интернет можно использовать сеорвис для проксирования запросов. Также возможно настроить 2FA, но пока этого не сделал.

Настройка Immich

Внешние библиотеки

Если посмотреть на файл .env, то там будут видны 2 переменные:

UPLOAD_LOCATION=./library
IMPORT_LOCATION=<path>

IMPORT_LOCATION отвечает за директорию откуда файлы будут импортироваться и сохраняться в UPLOAD_LOCATION по определенным правилам. Правила сохранения возможно настроить: Управление сервером -> Настройки -> Шаблон хранилища. Рекомендую сразу его включить и настроить.

Карта

Сервис извлекает геокоординаты из Ваших фотографий, но также и обратно геокодирует их, и таким образом обогащает полученные координаты находя географические объекты: страны, города и т.д. Настроить отображение карт возможно через: Управление сервером -> Настройки -> Настройки карты и GPS -> Настройки карты. У вас будут стандартные значения:

  1. tiles.immich.cloud/v1/style/light.json

  2. tiles.immich.cloud/v1/style/dark.json

Видно, что обращение идет к серверам Immich и возможно заменить на:

https://api.maptiler.com/maps/streets-v2/style.json?key=<key>

Для получения key нам необходимо перейти к MapTiler, зарегистрироваться и получить key. Тогда у нас карта будет примерно так выглядеть: По пути Управление сервером -> Настройки -> Настройки карты и GPS -> Настройки обратного геокодирования возможно также включить/отключить обратное геокодирование.

Модели машинного обучения

Рекомендую исправить: Управление сервером -> Настройки -> Настройки машинного обучения -> Интеллектуальный поиск. Я туда вставил модель: immich-app/nllb-clip-large-siglip. Полный список моделей можно увидеть тут. Сейчас мы выбрали мультиязыковую модель, чтобы иметь возможность искать на русском, а не только на английском. При этом поиск идет не по наименованию, а по изображению и распознанным внутри объектам (контекстный поиск).

Для распознавания лиц я выбрал модель: antelopev2 Проверить как работают сервисы на видеокарте возможно через переход по ssh на host, где работает Immich и выполнить:

nvidia-smi

Должны увидеть примерно такую картину:

По приборам видим, что видеокарта загружена. Команду Выше возможно также выполнить внутри контейнера, который отвечает за ML-задачи (immich-machine-learning).

Управление пользователями

Можно настроить разных пользователей, дать доступ к библиотеке 1 из пользователей и все будет работать отлично, но пользователю, которому вы дали доступ, не сможет видеть найденных лиц на фото с библиотеки основного пользователя. После недолгих раздумий сделал 1 пользователя для всей семьи, но уверен, что с течением времени и этот нюанс исправят, так как проект развивается довольно стремительно.

Интеграция с умным домом

Для интеграции возможно подключить интеграцию. Для работы нам потребуется выпустить API key в UI умного дома: Настройки учетной записи -> Ключи API -> Создать. Права оставляем только на чтение. Теперь можем просматривать альбомы, найденных людей и теги.

Мобильное приложение

Через F-Droid устанавливаем Immich.

Рекомендую настроить:

  1. Настройки -> Сеть -> Локальная сеть. Здесь указываем наименование нашей wi-fi сети и локальный адрес нашего сервиса.

  2. Настройки -> Сеть -> Внешняя сеть. Указываем внешний адрес нашего сервиса.

Теперь мобильное устройство будет знать какой адрес и в какой момент использовать для подключения к нашему сервису.

Итог

До этого я много лет использовал PhotoPrism и решил составить таблицу сравнения с текущим продуктом.

Критерий

PhotoPrism

Immich

Резервное копирование

Требуется стороннее приложение (например, PhotoSync) для автоматической загрузки с телефона.

Нативное мобильное приложение с автоматической фоновой загрузкой и поддержкой CLI для массового импорта.
Сам использую другое решение для синхронизации файлов между устройствами.

Организация файлов

Поддержка структуры папок по дате или сохранение исходной структуры. Мощные возможности организации через WebDAV.

Гибкая система шаблонов для структуры папок и названий файлов. Автоматическая миграция при изменении шаблонов.

Интерфейс и UX

Чистый веб-интерфейс, оптимизированный для десктопа. Нет нативных мобильных приложений (только PWA).

Современный интерфейс, вдохновленный Google Photos, с таймлайном и удобным мобильным приложением.

ИИ и поиск

Сильные возможности AI: распознавание объектов, лиц и мест. Однако пользователи отмечают нестабильность в распознавании лиц.

AI-теги и распознавание лиц активно развиваются. В 2025 году догоняет PhotoPrism, но пока может уступать в точности.

Безопасность

Базовая аутентификация по паролю. Нет MFA или OIDC (запланировано, но медленно развивается).

Поддержка OIDC и многофакторной аутентификации (MFA).

Производительность

Требует мощного железа (рекомендуется 16+ ГБ RAM, SSD). Медленная индексация больших библиотек.

Оптимизирована для скорости: быстрая загрузка и просмотр, даже для HEIC и RAW.

Совместный доступ

Создание общих альбомов по ссылкам. WebDAV позволяет напрямую редактировать файлы.

Простой обмен альбомами и фотографиями с контролем доступа.

Разработка

Медленное, но стабильное развитие. Некоторые функции (например, OIDC) годами в планах.

Очень активная разработка с частыми обновлениями и быстрым добавлением новых функций.

Лицензия и стоимость

Открытый исходный код (AGPL), но некоторые функции заблокированы behind paywall (например, расширенные роли пользователей).

Открытый исходный код (MIT), полностью бесплатный.

Настройка

Сложная настройка, требует ручного редактирования Docker-конфигурации.

Простая установка через Docker Compose с готовыми конфигурационными файлами.

Мультипользовательость

Одна библиотека на всех пользователей. Нет разделения контента.

Поддержка нескольких пользователей с раздельными библиотеками.

Мобильные возможности

Загрузка через сторонние приложения (например, PhotoSync). PWA-интерфейс для просмотра.

Нативные iOS и Android приложения для автоматической загрузки и офлайн-доступа.

Ключевые выводы для домашнего использования:

  1. Для автоматического резервного копирования с телефона лучше подходит Immich благодаря нативному мобильному приложению и беспроблемной фоновой загрузке.

  2. Для ценителей приватности и безопасности Immich предлагает более современные варианты аутентификации (OIDC, MFA).

  3. Если у вас большое количество фото и видео и вы готовы инвестировать в мощное железо, PhotoPrism может предложить немного более зрелые AI-возможности (но с оговорками на точность). Immich же менее требователен к ресурсам и обеспечивает большую скорость работы.

  4. Для простоты установки и использования Immich явный победитель благодаря простой настройке через Docker и интуитивному интерфейсу.

  5. Если вы планируете использовать сервис совместно с семьёй, Immich с поддержкой многопользовательского режима будет более практичным выбором.

Для большинства домашних пользователей, которые ищут простой, современный и удобный способ резервного копирования и просмотра фото с телефона, Immich на данный момент является более сильным кандидатом. PhotoPrism может быть интересен тем, кому критически важны его уникальные особенности вроде мощного WebDAV-интеграции и кто готов мириться с более сложной настройкой и отсутствием нативного мобильного приложения.

Ссылки:

  1. Зачем нужен собственный сервер в 2025?

  2. Как установить Proxmox?

  3. Как установить Docker?

  4. Как запустить прокси-сервер для сервисов?

  5. Как установить драйвера NVIDIA в Linux?

  6. Как запустить сервис по управлению умным домом?