pimenov.ai

База знаний

Immich — self-hosted фото-библиотека вместо Google Photos

Immich — self-hosted фото-библиотека вместо Google Photos: установка в Docker, распознавание лиц, CLIP-поиск, мобильный бэкап.

Опубликовано

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

Проект открытый, распространяется под лицензией GNU AGPL v3 и ставится через Docker Compose на VPS, мини-ПК или NAS. Сама установка занимает минут пятнадцать, а вот первичная обработка большой библиотеки — превью, распознавание лиц, векторы поиска — идёт часами. Это руководство покрывает полный цикл: требования к железу, установка, настройка поиска, рабочие сценарии и проверка результата.

📌
Для кого: те, кто хочет держать фото-архив у себя и готов работать с Docker Compose. Глубокого администрирования не требуется, но понимание томов, переменных окружения и бэкапов обязательно.

Что такое Immich

Immich — сервер для фото и видео с веб-интерфейсом и мобильными приложениями для iOS и Android. Внутри это несколько контейнеров: сервер, машинное обучение, кэш-сервис (Redis/Valkey) и Postgres с векторным расширением VectorChord, на котором работает контекстный поиск.

ЗадачаGoogle PhotosImmich
Хранение оригиналовКвота тарифа, сжатие при экономии местаОригиналы на своём диске, объём ограничен железом
СтоимостьПодписка за объёмСтоимость железа и электричества
Распознавание лицЕсть, на серверах GoogleЕсть, локально в ML-контейнере
Поиск по содержимомуЕстьCLIP-модель на выбор, включая многоязычные
ПриватностьДанные и метаданные у провайдераДанные и индексы остаются на вашем сервере
ЗрелостьПромышленный сервисАктивная разработка, ломающие изменения случаются
🔴
Главное предупреждение самого проекта: Immich не должен быть единственным местом, где живут ваши фото. Держите независимые копии по правилу 3-2-1 и не удаляйте архивы до того, как проверите восстановление.

Основные возможности

ВозможностьЧто даёт на практике
Мобильный автобэкапПриложение загружает новые снимки с телефона в фоне, включая выбранные альбомы
Таймлайн и альбомыХронологическая лента, альбомы, избранное, архив
Распознавание лицКластеры людей с именами, поиск по одному или нескольким лицам сразу
Контекстный поискСвободные запросы по содержимому кадра без ключевых слов в метаданных
Распознавание текстаOCR по изображениям: находит скриншоты, документы и вывески по тексту
Карта и геопоискГорода, регионы и страны из обратного геокодирования
Многопользовательский режимОтдельные библиотеки, общие альбомы, доступ для партнёра
Внешние библиотекиИндексация существующих папок на диске без переноса файлов внутрь Immich

Как устроен поиск

Поиск живёт в Postgres: метаданные и векторы CLIP лежат в одной базе, векторную часть обслуживает расширение VectorChord. Кроме свободных запросов доступны фильтры: люди, альбом, имя файла или расширение, папка исходного пути, описание, текст на изображении, локация, теги, камера и объектив, период, тип медиа, рейтинг.

Модель поиска выбирается в Administration → Settings → Machine Learning Settings → Smart Search. Модель по умолчанию быстрая, но качество ранжирования у более крупных моделей выше.

СценарийКакие модели смотреть
Запросы только на английскомViT-B-16-SigLIP2__webli — разумный дефолт: около 3 ГБ памяти, ~5,8 мс на запрос, 84,86% recall в тестах документации
Слабое железоViT-B-32-SigLIP2-256__webli — быстрее (~3,3 мс) при recall около 82%
Запросы в основном на русскомМодели nllb, например nllb-clip-base-siglip__v1 — тяжелее (~4,7 ГБ, ~15 мс), язык запроса берётся из настроек пользователя
Смешанные языки у одного человекаМодели xlm и siglip2 — понимают запрос независимо от текущего языка интерфейса
💡
После смены модели запустите переиндексацию: страница задач, кнопка «All» рядом с Smart Search. Без этого старые векторы останутся несовместимыми и в логах появятся ошибки обработки.

Требования к железу

ПараметрМинимумРекомендация
ОСLinux или другая Unix-подобная системаLinux на bare metal или в VM
RAM6 ГБ (4 ГБ только с отключённым ML)8 ГБ
CPU2 ядра4 ядра
Архитектураamd64 или arm64Для amd64 нужен уровень x86-64-v2 и выше
Файловая системаUnix-совместимая: EXT4, ZFS, APFSЛокальный SSD под данные Postgres
DockerDocker Engine и плагин ComposeКоманда docker compose, старый docker-compose не поддерживается

Под превью и транскоды закладывайте дополнительно 10–20% к размеру библиотеки. Файлы базы обычно занимают 1–3 ГБ.

⚠️
Где ломается чаще всего: DB_DATA_LOCATION должен указывать на локальный SSD. Сетевая шара, NTFS, exFAT или bind-mount из /mnt в WSL приведут к повреждению базы. В Windows и WSL используйте именованный том Docker: DB_DATA_LOCATION=pgdata плюс запись pgdata: в секции volumes:.

Запуск Docker внутри LXC-контейнера проект не рекомендует. Для amd64 последняя версия с поддержкой старых процессоров уровня x86-64-v1v2.7.5, и она больше не поддерживается.


Установка через Docker Compose

Шаг 1. Заготовка каталога

mkdir ./immich-app
cd ./immich-app
wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env

Шаг 2. Переменные окружения

ПеременнаяЗначение по умолчаниюЧто учитывать
UPLOAD_LOCATION./libraryМедиатека. Можно вынести на большой диск или массив
DB_DATA_LOCATION./postgresТолько локальный SSD, никогда не сетевое хранилище
TZзакомментированаРаскомментируйте и выставьте свой часовой пояс
IMMICH_VERSIONv3Для предсказуемых обновлений закрепите конкретную версию
DB_PASSWORDpostgresСмените. Используйте только латиницу и цифры
DB_USERNAME, DB_DATABASE_NAMEpostgres, immichМенять не обязательно

Шаг 3. Запуск

docker compose up -d

Веб-интерфейс поднимется на порту 2283, первый вошедший пользователь становится администратором.

⚠️
Типичные ошибки старта: unknown shorthand flag: 'd' in -d — установлен старый docker-compose вместо плагина Compose. permission denied при чтении .env — не хватает прав на файл или каталог. 'name' does not match any of the regexes: '^x-' — устаревшая версия Compose. can't set healthcheck.start_interval — нужен Docker Engine 25 и выше либо закомментируйте start_interval в секции database.

После установки

Структура хранения файлов

Storage template определяет, как сервер раскладывает оригиналы по папкам на диске. Шаблон по умолчанию — Year/Year-Month-Day/Filename.Extension, меняется в Administration → Settings → Storage Template. Настраивайте его до массовой загрузки: после смены шаблона существующие файлы перекладывает отдельная задача Storage Template Migration, и на большой библиотеке это надолго.

Аппаратное ускорение

На мини-ПК и NAS процессор упирается в двух местах: перекодирование видео и машинное обучение. Транскодинг ускоряется через NVENC (NVIDIA), Quick Sync (Intel), VAAPI (AMD, Intel, NVIDIA) и RKMPP (Rockchip). Включается это не галочкой: рядом с docker-compose.yml кладётся файл hwaccel.transcoding.yml из релиза, в сервисе immich-server раскомментируется секция extends, значение cpu меняется на нужный бэкенд, и только потом ускорение выбирается в настройках транскодинга. Для машинного обучения в документации есть отдельный раздел Hardware-Accelerated Machine Learning.

⚠️
Аппаратное ускорение работает только на Linux и на Windows через WSL2, причём Quick Sync в WSL2 недоступен, а Raspberry Pi не поддерживается. По умолчанию ускоряется только кодирование — аппаратное декодирование включается отдельной настройкой.

Практические сценарии

Перенос архива с телефона

  1. Установите мобильное приложение и укажите адрес сервера
  2. Войдите под своей учётной записью
  3. Включите бэкап и выберите альбомы устройства
  4. Оставьте телефон на зарядке в Wi-Fi до окончания первой загрузки
  5. Проверьте счётчик оставшихся файлов в разделе бэкапа

Индексация существующего архива на диске

Если фото уже лежат в структуре папок на NAS, не копируйте их внутрь медиатеки. Подключите каталог в docker-compose.yml и добавьте его как внешнюю библиотеку в Administration → External Libraries: Immich проиндексирует файлы и оставит их на месте.

Что важно знать заранее:

  • Монтируйте каталоги с флагом :ro. Без него Immich сможет удалить ваши исходники из веб-интерфейса.
  • В настройках библиотеки указывается путь, который видит контейнер, а не путь на хосте.
  • Библиотека принадлежит одному пользователю, и владельца нельзя сменить после создания.
  • Ненужное отсекайте exclusion patterns: **/Raw/** для сырых кадров, **/\@eaDir/** для служебных папок Synology.
  • Метаданные, добавленные внутри Immich (альбомы, описания), в файлы не записываются и теряются при перемещении файла в другое место библиотеки.
  • Удалённый с диска файл при пересканировании уходит в корзину и окончательно исчезает через 30 дней.
  • Автослежение за файловой системой помечено как экспериментальное и на сетевых дисках обычно не работает — полагайтесь на ночное пересканирование.
  • Просмотр по папкам включается отдельно: Account Settings → Features → Folders.

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

Общие альбомы подходят для событий, партнёрский доступ — для постоянного обмена библиотекой внутри семьи. Отдельные пользователи получают изолированные библиотеки на том же сервере.

Обновление

Закрепите версию в IMMICH_VERSION, читайте примечания к релизу и обновляйте контейнеры после свежего бэкапа базы. Проект развивается быстро, ломающие изменения встречаются.


Бэкапы и восстановление

Начиная с версии 2.5.0 Immich делает дампы базы сам: они складываются в UPLOAD_LOCATION/backups, по умолчанию создаются ежедневно в 2:00 и хранятся последние 14 штук. Расписание и глубину хранения меняют в Administration → Settings → Backup, разовый дамп запускают через Administration → Job Queues → Create job → Create Database Dump.

🔴
Дамп базы не содержит фотографий — только метаданные и пути к файлам. Бэкапом считается дамп плюс копия файлов, по отдельности они бесполезны.

Что копировать

ПапкаНасколько критичноЧто внутри
UPLOAD_LOCATION/uploadОбязательноОригиналы, загруженные из браузера, приложения и CLI
UPLOAD_LOCATION/libraryОбязательноОригиналы при включённом storage template
UPLOAD_LOCATION/profileОбязательноАватары пользователей
UPLOAD_LOCATION/backupsОбязательноАвтоматические дампы базы
thumbs, encoded-videoЖелательноПревью и перекодированные видео. Восстанавливаются задачами, но на большой библиотеке это часы работы

Порядок снятия копии

Лучший вариант — остановить контейнер immich-server на время бэкапа: тогда база и файлы гарантированно согласованы. Если останавливать нельзя, снимайте сначала базу, потом файлы. В худшем случае на диске окажутся файлы, о которых база не знает, — их можно дозалить руками. В обратном порядке база будет ссылаться на файлы, которых в копии нет, и вы получите битые ассеты.

Восстановление

Штатный путь — через интерфейс: Administration → Maintenance → Restore database backup, выбрать дамп из списка или загрузить .sql.gz. Перед восстановлением Immich создаёт точку отката и при неудаче возвращается к ней. На чистой установке тот же сценарий доступен на экране приветствия по кнопке «Restore from backup» — предварительно верните папки данных в новый UPLOAD_LOCATION.

Ручное восстановление через psql требует установки, в которой сервер ещё ни разу не запускался, либо переменной DB_SKIP_MIGRATIONS=true. Дампы, снятые до версии 2.5.0, восстанавливаются по инструкции для соответствующей версии документации.


Проверка результата

Что проверитьКак
Контейнеры живыdocker compose ps — все сервисы в состоянии running или healthy
Задачи обработкиСтраница очередей в администрировании: миниатюры, метаданные, Smart Search дошли до нуля
Машинное обучениеВ логах ML-контейнера нет ошибок, лица сгруппировались, свободный запрос выдаёт релевантные кадры
Мобильный бэкапСчётчик несинхронизированных файлов равен нулю, новые снимки появляются в таймлайне
ВосстановлениеДамп из UPLOAD_LOCATION/backups и копия файлов разворачиваются на чистой установке, где сервер ещё не запускался
⚖️
Копирование каталога DB_DATA_LOCATION на работающем сервере бэкапом не считается. Рабочая копия — это дамп из UPLOAD_LOCATION/backups плюс файлы медиатеки.

Антипаттерны

АнтипаттернПочему плохоЧто делать вместо
Удалить фото из облака сразу после загрузкиПроект прямо предупреждает не использовать себя как единственное хранилищеДождаться проверенного восстановления и держать вторую копию
База Postgres на сетевом дискеПовреждение данных и падения сервераЛокальный SSD или именованный том Docker
Тег latest вместо версииОбновление приезжает без вашего решенияЗакреплённый IMMICH_VERSION и чтение релиз-нотов
Сервер, открытый в интернет напрямуюЛичный архив на неподготовленном хосте становится цельюVPN или обратный прокси с HTTPS и аутентификацией
Пароль базы из примераДефолтные значения известны всемСвой пароль из латиницы и цифр в .env
Тяжёлая CLIP-модель на слабом железеОчереди обработки не заканчиваются, поиск тормозитМодель поменьше, оценка памяти и времени по таблицам документации

Чеклист

Подготовка

Хост соответствует требованиям по RAM, CPU и архитектуре
Под медиатеку выделен диск с запасом на превью и транскоды
Под данные Postgres выделен локальный SSD или том Docker
Установлен Docker Engine с плагином Compose

Установка

Скачаны docker-compose.yml и .env из последнего релиза
Заполнены UPLOAD_LOCATION, DB_DATA_LOCATION, TZ
Изменён DB_PASSWORD
Закреплена версия в IMMICH_VERSION
Сервер отвечает на порту 2283, создан администратор

Настройка

Storage template настроен до массовой загрузки
Выбрана CLIP-модель под язык запросов и возможности железа
Переиндексация Smart Search выполнена после смены модели
Подключены внешние библиотеки с флагом :ro и exclusion patterns, если архив уже лежит на диске
Включено аппаратное ускорение транскодинга, если позволяет железо
Настроены пользователи, общие альбомы и партнёрский доступ
Мобильный бэкап включён на всех устройствах

Эксплуатация

Проверено расписание автоматических дампов в Administration → Settings → Backup
Папки upload, library, profile и backups копируются вне сервера
Копия снимается при остановленном immich-server либо в порядке «сначала база, потом файлы»
Тестовое восстановление на чистой установке выполнено
Доступ извне закрыт VPN или прокси с HTTPS

Полезные ссылки


По теме

Собрать фото-архив у себя проще, чем кажется, а вот эксплуатация и бэкапы требуют дисциплины. Если захотите обсудить, как это применить у себя или в команде — пишите в Telegram @pimenov