Immich в Docker Compose: готовый файл
Google Photos бесплатно кончился, а платная подписка не даёт ответа на вопрос, куда на самом деле уходят ваши семейные фото и что с ними будет через пять лет смены политики компании. Immich решает это тем же способом, каким решают такие вопросы обычно — переносом данных на сервер, который контролируете вы: мобильное приложение с автозагрузкой в фоне, распознавание лиц и объектов, таймлайн, шаринг альбомов — но всё крутится на вашем VPS. Ниже — рабочий docker-compose.yml, который поднимает Immich с нуля, и разбор мест, где новички обычно спотыкаются: от прав на volume до того, зачем базе данных нужно специфическое расширение PostgreSQL.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что понадобится перед стартом
Immich не такой лёгкий, как обычный self-hosted сервис из одного контейнера — это связка из четырёх компонентов: сервер приложения, PostgreSQL с векторным расширением (под поиск по содержимому фото), Redis для очередей задач и отдельный сервис машинного обучения. Заранее прикиньте ресурсы:
- CPU — от 2 vCPU. Машинное обучение (распознавание лиц, объектов, поиск по смыслу) грузит процессор при импорте партиями фото; на 1 vCPU это будет тянуться заметно дольше, чем на 2-4.
- RAM — от 4 ГБ для комфортной работы; 2 ГБ тоже заведутся, но с урезанным ML или без него.
- Диск — здесь главный вопрос не производительность, а объём: библиотека фото растёт быстро, и лучше сразу закладывать запас, а не переезжать на больший диск через полгода. Логика расчёта есть в статье сколько дискового пространства закладывать с запасом.
- Docker и Docker Compose — если ещё не установлены, разбор есть в статье про установку Docker на Ubuntu 24.04.
Отдельный момент — GPU. Immich умеет ускорять машинное обучение через видеокарту (NVIDIA, а на части сборок — Intel QuickSync или AMD), но это не обязательно: без GPU распознавание просто идёт на CPU медленнее. Для домашнего архива на несколько тысяч фото CPU обычно достаточно, GPU имеет смысл при библиотеке на десятки тысяч снимков или при желании обрабатывать импорт мгновенно.
Готовый docker-compose.yml
Создайте рабочую директорию:
mkdir -p ~/immich && cd ~/immich
Официальный проект Immich развивается быстро, поэтому вместо того чтобы копировать состав сервисов вручную, разумнее один раз скачать актуальный docker-compose.yml и файл примера окружения с GitHub проекта (immich-app/immich, ветка main, каталог docker/) — они меняются от релиза к релизу, и лучше ориентироваться на них, а не на застывший в статье список версий образов. Ниже — рабочий скелет, отражающий структуру, которая была стабильной на момент написания:
name: immich
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:release
restart: unless-stopped
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
- /etc/localtime:/etc/localtime:ro
env_file:
- .env
ports:
- "2283:2283"
depends_on:
- redis
- database
healthcheck:
disable: false
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:release
restart: unless-stopped
volumes:
- model-cache:/cache
env_file:
- .env
redis:
container_name: immich_redis
image: docker.io/valkey/valkey:8-bookworm
restart: unless-stopped
volumes:
- redis-data:/data
database:
container_name: immich_postgres
image: ghcr.io/immich-app/postgres:14-vectorchord0.3.0-pgvectors0.2.0
restart: unless-stopped
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
POSTGRES_INITDB_ARGS: "--data-checksums"
volumes:
- pgdata:/var/lib/postgresql/data
shm_size: 128mb
volumes:
model-cache:
redis-data:
pgdata:
Ключевой нюанс, который многих путает: PostgreSQL здесь не обычный postgres:16 из Docker Hub, а образ с предустановленным векторным расширением (vectorchord или его предшественник pgvecto.rs) — оно нужно для поиска "похожих" фото по смысловому содержимому, а не только по тегам. Если подставить сюда чистый официальный образ Postgres, Immich не запустится или упадёт на миграции базы.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверФайл .env и структура каталогов
Создайте .env рядом с docker-compose.yml:
nano .env
Минимальный набор переменных:
# Куда физически складывать фото и видео на диске сервера
UPLOAD_LOCATION=./library
# База данных
DB_PASSWORD=замените-на-длинный-случайный-пароль
DB_USERNAME=immich
DB_DATABASE_NAME=immich
# Версия — release тянет актуальный стабильный релиз,
# зафиксируйте конкретный тег (например 1.118.2), когда захотите
# обновляться осознанно, а не автоматически при каждом up
IMMICH_VERSION=release
# Часовой пояс для корректных таймстампов в интерфейсе
TZ=Europe/Moscow
Пароль базы сгенерируйте, не пишите вручную "на глаз":
openssl rand -base64 24
UPLOAD_LOCATION стоит указывать не относительным путём внутри домашней директории, а на отдельный примонтированный диск, если он есть у вашего тарифа — фотоархив со временем становится тяжелее всей остальной системы вместе взятой, и удобнее держать его физически отдельно. Про то, как устроены разные типы volume в Docker и почему bind-mount на конкретный путь надёжнее анонимного volume для данных, которые нужно бэкапить руками, — в статье про типы Docker volumes.
Первый запуск и вход в веб-интерфейс
Поднимаем стек и смотрим логи, пока сервисы стартуют:
docker compose up -d
docker compose logs -f immich-server
При первом старте immich-server дожидается, пока база данных пройдёт миграции — это может занять минуту-другую, торопиться не нужно. Признак готовности — сообщение о том, что сервер слушает порт 2283, и отсутствие ошибок подключения к базе в логах.
Дальше открываете http://ваш-IP-или-домен:2283 в браузере — на первом экране Immich просит создать администратора: email и пароль, локально, без внешней регистрации. После входа доступны:
- Мобильное приложение (iOS и Android) — устанавливается отдельно, при первом запуске указываете адрес сервера и логинитесь тем же аккаунтом. В настройках приложения включается автобэкап — фото и видео с телефона начинают синхронизироваться в фоне, аналогично тому, как это делал Google Photos.
- Веб-интерфейс — тот же функционал: таймлайн, альбомы, поиск, шаринг ссылками.
Проверьте, что доступ по порту 2283 не открыт без надобности всему интернету — на этапе тестирования это нормально, но перед тем как начать заливать личный архив, стоит закрыть прямой доступ и перейти на HTTPS через reverse proxy (следующий раздел) либо ограничить порт через VPN.
HTTPS-доступ через reverse proxy
Мобильное приложение Immich умеет работать и без HTTPS в локальной сети, но для доступа из любой точки интернета (а смысл self-hosted фотохостинга обычно именно в этом — фото должны заливаться, пока вы в дороге, а не только дома) нужен нормальный TLS-сертификат, иначе часть функций приложения будет капризничать, а трафик с паролем от аккаунта пойдёт открытым текстом.
Проще всего поднять Traefik как reverse proxy перед immich-server — он сам получает и продлевает сертификаты Let's Encrypt. Пошаговая установка разобрана в статье про Traefik на VPS, а если предпочитаете классическую связку nginx + certbot — есть отдельный разбор установки Let's Encrypt SSL на VPS. В обоих случаях прокси просто перенаправляет запросы с 443 порта на 2283 внутри docker-сети, а порт 2283 из docker-compose.yml после этого можно вообще не публиковать на хосте (убрать секцию ports у immich-server, оставив только внутреннюю docker-сеть между контейнерами).
Машинное обучение: лица, объекты, CPU или GPU
Сервис immich-machine-learning отвечает за то, что отличает Immich от простого файлового хранилища фото:
- распознавание и группировка лиц (можно вручную подписывать "это мама", и дальше фото группируются автоматически);
- определение объектов и сцен на фото для текстового поиска ("пляж", "собака", "закат") без ручных тегов;
- поиск по смысловому сходству изображений (CLIP-модели).
На CPU это работает, но заметно медленнее, чем на GPU — особенно при первом массовом импорте архива за несколько лет, когда модели нужно прогнать через тысячи файлов разом. Если сервер слабый и импорт растягивается на дни, есть два честных варианта: смириться и дать процессу идти в фоне (после первичной обработки новые фото добавляются по одной и заметной нагрузки не создают), либо временно отключить ML-контейнер в .env (MACHINE_LEARNING_ENABLED=false) и включить его позже на более мощном тарифе, когда архив уже залит.
Для GPU-ускорения на NVIDIA-картах нужен установленный nvidia-container-toolkit на хосте и добавленная секция deploy.resources.reservations.devices у сервиса immich-machine-learning в compose-файле — конкретный синтаксис меняется между версиями Docker Compose, актуальный пример стоит смотреть в docker/docker-compose.ml.yml из репозитория проекта, там его поддерживают в актуальном состоянии под текущий релиз.
Автобэкап с телефона и резервное копирование базы
Автобэкап с телефона настраивается в приложении: Settings → Backup — включается фоновая загрузка, можно ограничить только загрузкой по Wi-Fi, чтобы не тратить мобильный трафик. Важно понимать разницу с оригинальным Google Photos: Immich по умолчанию не удаляет оригиналы с телефона и не сжимает фото — грузит как есть, поэтому первый полный бэкап большой библиотеки может занять часы и заметно нагрузить и телефон, и канал сервера.
Сам сервер тоже нужно бэкапить — и здесь два независимых объекта: файлы (UPLOAD_LOCATION) и база данных PostgreSQL. Файлы можно синхронизировать во внешнее хранилище через rclone — готовый рабочий пример есть в статье Rclone в Docker Compose. Базу данных бэкапить отдельно, штатным pg_dump из контейнера:
docker exec immich_postgres pg_dumpall -c -U immich > immich_db_backup_$(date +%F).sql
Разумно повесить это на cron раз в сутки и хранить хотя бы неделю бэкапов, ротируя старые. Восстановление — из дампа через psql в свежий контейнер базы данных, после чего запускается immich-server, который сверяет состояние с файлами на диске.
Если после активного использования на сервере начинает заканчиваться место — это почти всегда либо разросшийся фотоархив (ожидаемо), либо забытые старые образы и volume-ы после апгрейдов Immich; в статье про Docker, занимающий всё место на диске, разобрано, как отличить одно от другого и почистить безопасно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Immich бесплатный?
Да, проект открытый (AGPL), без подписки и без ограничений на число фото — платите только за сервер, на котором он работает.
Можно ли перенести архив из Google Photos в Immich?
Да, есть отдельная CLI-утилита immich-go для массового импорта архивов, выгруженных через Google Takeout, с сохранением дат съёмки и альбомов. Это отдельный инструмент, не входящий в основной compose-стек.
Что будет с фото, если сервер выключить или удалить?
Ровно то же, что с любыми данными на диске — если не настроен внешний бэкап, они исчезнут вместе с сервером. Immich не хранит копию нигде, кроме диска, который вы ему выделили, поэтому вынесенный на внешнее хранилище бэкап — не опция, а обязательный пункт для реального архива.
Чем Immich отличается от Nextcloud для хранения фото?
Nextcloud — универсальное файловое хранилище с модулем "Фото" поверх; Immich — специализированное приложение именно под фото и видео, с более удобным мобильным клиентом для автозагрузки и более развитым распознаванием лиц/объектов из коробки. Если нужен ещё и офисный документооборот, календари, контакты — Nextcloud шире; если задача именно "заменить Google Photos" — Immich точнее попадает в неё.
Нужен ли статический IP или домен?
Домен не обязателен для работы через IP, но сильно упрощает получение TLS-сертификата и подключение мобильного приложения без ручной перенастройки адреса при каждой смене IP.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →