MAATRIX / Блог / PhotoPrism на сервере: частые ошибки и решения

PhotoPrism на сервере: частые ошибки и решения

MAATRIX

Google Фото и iCloud удобны, пока не упрётесь в лимит подписки или не задумаетесь, кто на самом деле смотрит ваши семейные архивы. PhotoPrism — открытый self-hosted аналог с ИИ-тегированием, распознаванием лиц и поиском по содержимому кадра, который вы поднимаете на своём сервере и полностью контролируете. Но между «работает у автора в README» и «работает у вас на VPS» есть разрыв: индексация зависает, ИИ-модуль падает без внятной ошибки, MariaDB упирается в лимиты, а диск незаметно кончается. Разберём конкретные причины и рабочие решения для каждой из этих ситуаций.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Фото не индексируются или импорт зависает на 0%

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

Права доступа на том с оригиналами. PhotoPrism внутри контейнера работает от пользователя с конкретным UID/GID, и если примонтированная директория /photoprism/originals принадлежит другому пользователю на хосте, демон индексации просто не видит файлы или падает на попытке прочитать метаданные. Проверьте владельца:

ls -la /srv/photoprism/originals

и приведите его в соответствие с переменными окружения контейнера:

environment:
  PHOTOPRISM_UID: "1000"
  PHOTOPRISM_GID: "1000"
sudo chown -R 1000:1000 /srv/photoprism/originals

Несовпадение путей. PHOTOPRISM_ORIGINALS_PATH внутри контейнера должен указывать ровно туда, куда вы примонтировали volume, иначе индексатор просто не находит файлов — не потому что их нет, а потому что смотрит не туда. Проверяйте docker-compose.yml построчно, особенно если копировали конфиг из чужого гайда с другой структурой каталогов.

Лимит открытых файлов. При большом архиве (десятки тысяч файлов) индексатор может упираться в системный ulimit на количество открытых файловых дескрипторов, особенно на VPS с урезанными лимитами по умолчанию. Если в логах контейнера мелькает too many open files, поднимите лимит на хосте и для самого контейнера:

services:
  photoprism:
    ulimits:
      nofile:
        soft: 65536
        hard: 65536

После правки любого из этих пунктов перезапустите индексацию через docker compose restart photoprism, а не просто через веб-интерфейс — часть настроек читается только при старте контейнера.

ИИ-теггирование и распознавание лиц падают или зависают

PhotoPrism использует встроенный модуль на базе TensorFlow для классификации сцен, объектов и лиц. Именно этот компонент чаще всего становится источником непонятных сбоев на арендованных серверах.

Главная причина — процессор без поддержки инструкций AVX. TensorFlow-сборка, которую использует PhotoPrism, рассчитана на современные наборы инструкций, и на старых или сильно урезанных виртуальных CPU (типичная ситуация для бюджетных VPS с процессорами прошлых поколений) индексация с ИИ либо зависает, либо контейнер падает без внятной записи в логах приложения — смотреть нужно dmesg или логи Docker на предмет illegal instruction. Проверить поддержку AVX на сервере просто:

grep -o 'avx[0-9]*' /proc/cpuinfo | sort -u

Если AVX отсутствует, единственный надёжный вариант — отключить ИИ-модуль и жить с ручной сортировкой по альбомам и датам:

environment:
  PHOTOPRISM_DISABLE_TENSORFLOW: "true"

Второй частый сценарий — не падение, а зависание на конкретном файле: индексатор доходит до одной фотографии (часто это HEIC/HEIF с iPhone или повреждённый RAW) и молча стоит часами. Проверяйте прогресс через логи в реальном времени:

docker compose logs -f photoprism | grep -i index

и если видите, что процесс не двигается больше 10-15 минут на одном файле — это почти всегда битый исходник, который стоит вручную вынести из папки импорта и разобрать отдельно.

Отдельно стоит закладывать ресурсы под сам ИИ-модуль: распознавание лиц и объектов заметно грузит CPU и оперативную память во время первичной индексации большого архива, особенно на многопоточном прогоне. Ориентировочно для комфортной работы с активным ИИ-модулем стоит закладывать от 4 ГБ RAM и больше — точная цифра зависит от размера архива и числа воркеров, поэтому лучше стартовать с запасом и смотреть на docker stats в первые сутки индексации.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

MariaDB отваливается: too many connections и медленные запросы

PhotoPrism хранит метаданные, теги и индекс лиц в MariaDB (SQLite годится только для теста на паре сотен фото — на реальном архиве она станет узким местом почти сразу). Из типовых проблем БД в связке с PhotoPrism:

Ошибка подключения при старте. Контейнер PhotoPrism стартует быстрее, чем MariaDB успевает поднять сервис, и падает с connection refused. Лечится depends_on с проверкой здоровья, а не просто порядком запуска:

services:
  mariadb:
    image: mariadb:11
    healthcheck:
      test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
      interval: 10s
      retries: 6
  photoprism:
    depends_on:
      mariadb:
        condition: service_healthy

Too many connections. При параллельной индексации нескольких воркеров PhotoPrism может открывать больше соединений, чем разрешено по умолчанию в MariaDB. Поднимите лимит в конфиге БД:

[mysqld]
max_connections = 200
innodb_buffer_pool_size = 512M

Значение innodb_buffer_pool_size подбирайте под доступную память сервера — общие принципы тюнинга MariaDB под нагрузку описаны в статье про частые ошибки MariaDB на сервере, рекомендации оттуда полностью применимы и здесь.

Медленный поиск по большому архиву. На десятках тысяч фото без должного тюнинга поиск и построение галереи начинают заметно тормозить. Прежде чем гнаться за более мощным сервером, проверьте базовые вещи: не переполнен ли диск под данными MariaDB, не идёт ли параллельно фоновая индексация, и включён ли innodb_buffer_pool_size достаточного размера, чтобы горячие данные помещались в память.

Диск неожиданно заканчивается

RAW-файлы и оригиналы в высоком разрешении быстро съедают место, а PhotoPrism дополнительно создаёт превью, кэш миниатюр и sidecar-файлы с метаданными — реальный объём на диске обычно заметно больше суммарного веса исходных фото.

Если сервер внезапно упёрся в 100% занятого диска, первым делом проверьте, где именно накопился объём:

du -sh /srv/photoprism/*

Чаще всего разрастается директория storage/cache — превью и миниатюры, которые PhotoPrism пересоздаёт при необходимости, поэтому её можно безопасно чистить:

docker compose exec photoprism photoprism cleanup

Эта же команда полезна как регулярная задача в cron — она убирает устаревшие превью и временные файлы без риска задеть оригиналы. Для оригиналов держите отдельный том с запасом минимум 2-3x от текущего архива, если планируете продолжать снимать и загружать — миграция большого архива на новый диск без простоя описана в статье про замену диска без простоя на RAID, если у вас конфигурация с RAID-массивом.

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

Веб-интерфейс не открывается или обрывается через reverse-proxy

Если PhotoPrism вынесен за Traefik или nginx (а на продакшене он почти всегда должен быть за прокси с HTTPS, а не голым портом наружу), встречаются две типовые проблемы.

Загрузка больших файлов обрывается. По умолчанию прокси часто ограничивает размер тела запроса значением, недостаточным для RAW-файлов в десятки мегабайт. Для Traefik лимит настраивается через middleware:

labels:
  - "traefik.http.middlewares.photoprism-buffering.buffering.maxRequestBodyBytes=104857600"
  - "traefik.http.routers.photoprism.middlewares=photoprism-buffering"

Общие проблемы конфигурации Traefik на сервере — таймауты, сертификаты, лейблы — разобраны в статье про частые ошибки Traefik на сервере.

Разрывается соединение при живом обновлении прогресса индексации. PhotoPrism использует WebSocket для отображения прогресса в реальном времени, и если прокси не настроен на апгрейд соединения, интерфейс просто не показывает статус (сама индексация при этом идёт нормально в фоне). Убедитесь, что заголовки Connection: Upgrade и Upgrade: websocket проходят через прокси — для Traefik это работает из коробки, для nginx нужно явно прописать в конфиге локации:

location / {
    proxy_pass http://photoprism:2342;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
}

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

Резервное копирование и восстановление после сбоя

PhotoPrism хранит данные в двух разных местах — файлы оригиналов на диске и метаданные/индекс лиц в MariaDB, — и бэкапить нужно оба, причём согласованно. Резервная копия только файлов без дампа базы означает, что после восстановления вы получите фотографии без тегов, альбомов и распознанных лиц — придётся переиндексировать архив заново, а это часы работы на большом объёме.

Минимальный рабочий скрипт для регулярного бэкапа:

#!/bin/bash
docker compose exec -T mariadb mariadb-dump -u photoprism -p"$DB_PASSWORD" photoprism > /backup/photoprism-db-$(date +%F).sql
rsync -a /srv/photoprism/originals/ /backup/originals/

Общие принципы построения бэкап-стратегии для связки Docker + MySQL/MariaDB подробно разобраны в статье про бэкап MySQL на сервере — рекомендации по ротации копий и проверке восстановления применимы и к MariaDB под PhotoPrism без изменений. Обязательно раз в несколько месяцев проверяйте, что дамп реально разворачивается на тестовом окружении — бэкап, который никогда не восстанавливали, нельзя считать рабочим.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

PhotoPrism бесплатный?

Ядро распространяется под открытой лицензией и его можно развернуть самостоятельно бесплатно, но часть продвинутых функций (некоторые режимы распознавания, приоритетная поддержка) доступна по платной подписке Plus/Team от разработчиков — для домашнего архива обычно достаточно бесплатной версии.

Чем PhotoPrism отличается от Immich?

Оба — self-hosted альтернативы Google Фото. PhotoPrism делает акцент на классификацию по содержимому кадра и зрелый веб-интерфейс, Immich — на быстрое мобильное приложение с автоматической синхронизацией со смартфона. Многие держат оба и сравнивают на своих данных, готового универсального ответа "что лучше" нет.

Нужен ли GPU для ИИ-тегирования?

Нет, штатный ИИ-модуль PhotoPrism работает на CPU через TensorFlow. GPU не задействуется и не ускоряет индексацию — важнее наличие инструкций AVX у процессора и достаточный объём RAM.

Можно ли использовать SQLite вместо MariaDB?

Технически да, и для тестового запуска на небольшом числе фото это работает. Но при реальном архиве в тысячи файлов SQLite становится узким местом на конкурентных операциях, и разработчики сами рекомендуют MariaDB для продакшена.

Как перенести PhotoPrism на другой сервер?

Перенести volume с оригиналами, дамп базы MariaDB и файл .env с переменными окружения — после разворачивания на новом сервере переиндексация не потребуется, если структура путей внутри контейнера совпадает с исходной.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →