Immich: скільки RAM потрібно та як безпечно оновлювати
Дізнайтеся чесну потребу в RAM, налаштуйте порт 2283 за HTTPS, виправте завершення з кодом 137 і запустіть Immich v3 без несумісного pgvecto.rs.
Що ви створюєте
Immich — це self-hosted сервіс для резервного копіювання фотографій і відео, повноцінна заміна Google Photos. Він має мобільний застосунок, який працює у фоновому режимі та завантажує фотографії з камери, часову шкалу, альбоми, розпізнавання облич і пошук на основі машинного навчання, який знаходить «пляж» або потрібну людину без ручного додавання тегів. Ви запускаєте його на власному VPS, оригінальні файли залишаються на вашому диску, і ніхто не сканує їх для показу реклами. Якщо ви ще порівнюєте Immich з іншим очевидним кандидатом, у нашому порівнянні PhotoPrism та Immich наведено їхні мінімальні вимоги до RAM, мобільні застосунки та команди резервного копіювання.
Встановлення складається з чотирьох контейнерів із власного Docker Compose-файлу проєкту. Це займає десять хвилин. Решта проблем виникає саме під час подальшого налаштування: контейнер машинного навчання потребує багато пам’яті на малопотужному сервері, оригінали швидко заповнюють диск, мобільний застосунок відмовляється працювати із сервером через звичайний HTTP, а Immich досить часто випускає зміни, що порушують сумісність, тому необережний docker compose pull може зробити базу даних нездатною запуститися. Ставтеся до цих чотирьох аспектів серйозно — і Immich працюватиме стабільно. Ігноруйте їх — і втратите цілі вихідні.
Попередні вимоги та важливі нюанси
- ОЗП: в офіційній документації вказано мінімум 6 GB і рекомендовано 8 GB; вважайте 4 GB разом зі swap абсолютним мінімумом. Контейнери
immich-serverі Postgres споживають небагато ресурсів. Контейнерimmich-machine-learningє основним споживачем пам’яті: він завантажує моделі CLIP і розпізнавання облич в ОЗП для побудови пошукових індексів, а на сервері з 2 GB ядро його завершує. Додайте swap, навіть якщо маєте 4 GB. - Диск: розрахуйте обсяг для всієї бібліотеки та передбачте запас. Оригінали копіюються повністю. Крім того, Immich створює мініатюри й зображення попереднього перегляду — це приблизно ще 10–20%. Для фотоколекції обсягом 200 GB потрібен том на 300 GB. Порівняно з цим Postgres займає мало місця.
- CPU: будь-який сучасний KVM VPS підходить, але ML на CPU працює повільно. Індексація smart search для великого імпорту може тривати кілька годин у фоновому режимі. Це нормально; GPU не потрібен.
- Доменне ім’я, спрямоване на VPS. Мобільний застосунок наполегливо рекомендує HTTPS endpoint, а перед ним потрібен reverse proxy. Це така сама схема, як у self-hosted інстансу Nextcloud із Docker, TLS і резервними копіями; Immich є аналогом цього файлового сервера для фотографій.
- Docker і Compose plugin, встановлені з Docker Engine та Compose v2 plugin із власного apt-репозиторію Docker, як описано в нашому посібнику з основ Docker Compose.
Крок 1: Спочатку додайте swap
Найпоширеніша причина збоїв Immich на невеликому VPS — завершення роботи ML-контейнера через OOM. Спочатку надайте ядру додатковий простір для роботи.
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab
free -hТепер free -h має показувати рядок Swap: зі значенням 4.0Gi. Це не пришвидшить ML, але контейнер не завершуватиме роботу посеред індексації на машині з 4 GB оперативної пам’яті.
Крок 2: Завантажте офіційні compose-файли та env-файл і використовуйте їх, а не копію
Immich фіксує версії своїх сервісів і, що особливо важливо, образ бази даних у файлах, які постачає разом із релізом. Не використовуйте compose-файл із блогу, зокрема з цього матеріалу, як єдине джерело конфігурації. Завантажте файли релізу:
sudo mkdir -p /opt/immich && cd /opt/immich
sudo wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml
sudo wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.envЦі файли походять із позначеного тегом релізу, тому посилання на образи відповідають одна одній. Compose-файл визначає чотири сервіси. Перш ніж щось змінювати, варто знати призначення кожного з них:
immich-server(ghcr.io/immich-app/immich-server, контейнерimmich_server) — API та вебінтерфейс, який прослуховує порт2283. Він монтує завантажені файли в/data.immich-machine-learning(ghcr.io/immich-app/immich-machine-learning, контейнерimmich_machine_learning) — пошук CLIP і розпізнавання облич. Завантажені моделі кешуються у томіmodel-cache. Цей сервіс споживає найбільше пам’яті.database(контейнерimmich_postgres) — Postgres із векторним розширенням VectorChord, яке забезпечує пошук за схожістю. Тег образу зафіксовано за digest безпосередньо в compose-файлі, наприкладghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:.... У старіших конфігураціях використовувавсяpgvecto.rs; підтримку цього варіанта вилучено в Immich v3.0, тому все, що ви встановлюєте сьогодні, використовує VectorChord. Ніколи не змінюйте цей тег вручну.redis(контейнерimmich_redis) — екземпляр Valkey/Redis для черг завдань.
Крок 3: Налаштуйте .env, де зберігаються ваші фотографії та база даних
Відкрийте .env і налаштуйте чотири параметри. Усе нижче позначеного рядка залиште без змін.
# Where original uploads are stored on the host
UPLOAD_LOCATION=/opt/immich/library
# Where the Postgres data lives. NEVER put this on an NFS/network share.
DB_DATA_LOCATION=/opt/immich/postgres
# "v3" is a floating tag that tracks the latest v3.x. Pin a full tag like
# v3.0.2 instead — then you upgrade on purpose, not by surprise.
IMMICH_VERSION=v3.0.2
# Change this to a long random string. Letters and digits only.
DB_PASSWORD=REPLACE_WITH_A_LONG_RANDOM_STRING
# Set your timezone so timestamps and "on this day" line up
TZ=Europe/London
###################################################################################
DB_USERNAME=postgres
DB_DATABASE_NAME=immichДва правила, які допоможуть уникнути проблем. UPLOAD_LOCATION має вказувати на великий диск. Якщо пізніше ви підключите том даних, відразу вкажіть тут шлях до його монтування, оскільки після цього доведеться переносити мініатюри й оновлювати шляхи до ресурсів. DB_DATA_LOCATION має розташовуватися на локальному диску: Postgres пошкоджує дані на спільному ресурсі NFS або SMB, і в документації про це сказано прямо. Якщо використовувати в DB_PASSWORD лише літери й цифри, можна уникнути певного класу помилок екранування в рядку підключення.
Крок 4: Перший запуск і створення облікового запису адміністратора
cd /opt/immich
sudo docker compose up -d
sudo docker compose psПравильний результат — чотири контейнери, усі running і зрештою healthy:
NAME STATUS
immich_machine_learning Up (healthy)
immich_postgres Up (healthy)
immich_redis Up (healthy)
immich_server Up (healthy)Перший up завантажує кілька гігабайтів образів, тому зачекайте. Переглядайте перебіг виконання за допомогою sudo docker compose logs -f immich-server; коли сервер буде готовий, у журналі з’явиться повідомлення, що він прослуховує порт 2283. Тепер відкрийте http://YOUR_SERVER_IP:2283 у браузері. Під час першого відвідування відкриється майстер Getting Started. Перший створений обліковий запис буде обліковим записом адміністратора. Задайте надійний пароль. Цей обліковий запис керує налаштуваннями сервера, користувачами та конфігурацією ML, яка знадобиться пізніше.
Крок 5: Мобільний застосунок і резервне копіювання у фоновому режимі
Установіть Immich з App Store або Play Store. На екрані входу застосунок запитує Server Endpoint URL. Укажіть повну URL-адресу зі схемою, наприклад https://photos.example.com (застосунок сам додає /api). Увійдіть за допомогою щойно створеного облікового запису, відкрийте екран Backup, виберіть альбоми для резервного копіювання (зазвичай Camera і Screenshots) і ввімкніть Background backup. В iOS фонове резервне копіювання обмежується операційною системою. Завантаження у foreground виконується завжди, а у фоновому режимі — лише коли це дозволяє операційна система.
Саме на цьому етапі найчастіше виникають проблеми, тому прочитайте Крок 6, перш ніж намагатися виправити роботу застосунку.
Крок 6: HTTPS через reverse proxy та правило повної URL-адреси
Мобільному застосунку потрібен HTTPS. Розмістіть reverse proxy перед портом 2283 і завершуйте TLS на ньому. Якщо ви вже запускаєте кілька контейнерів, Traefik з автоматичним TLS для кількох Docker-застосунків є найакуратнішим варіантом: один блок labels направляє photos.example.com до контейнера immich-server і сам отримує сертифікат. Якщо ви надаєте перевагу nginx, посібник Let's Encrypt із Certbot і nginx допоможе отримати сертифікат і блок proxy_pass http://127.0.0.1:2283;. Коли reverse proxy вже налаштований, додавання наступного сервісу здебільшого зводиться до створення нового піддомену. Саме так медіафронтенд на кшталт Halcyon, оболонки відеомагазину 90-х для Jellyfin опиняється поруч з Immich на тому самому сервері. Те саме стосується self-hosted HarnessRouter, який розміщує Codex і Claude Code за одним API. Він навмисно прив’язаний до loopback і стає доступним лише після завершення TLS на reverse proxy перед ним. Тому змініть його стандартні облікові дані до того, як спрямовувати на нього піддомен. Однак не кожен контейнер потребує публічного hostname. Адміністративний інструмент на кшталт self-hosted сканера безпеки open-kritt краще взагалі не підключати до reverse proxy, а відкривати його вебінтерфейс через SSH tunnel лише за потреби. Інші сервіси не використовують reverse proxy, оскільки HTTP їм не підходить. Найкращий приклад — self-hosted relay-сервер RustDesk. Він прослуховує кілька звичайних TCP- і UDP-портів і потребує правил firewall, а не піддомену. Для Immich важливе одне налаштування reverse proxy: збільште ліміт розміру завантаження, оскільки відео з телефона мають великий розмір. У nginx це client_max_body_size 50000M; всередині server block. Стандартний ліміт 1 MB відхиляє завантаження відео з помилкою 413 Request Entity Too Large.
Правило, яке застосунок перевіряє: endpoint має бути доступним і на практиці має використовувати HTTPS. Endpoint-и http:// або пряма IP-адреса без зазначеного порту спричиняють помилку «застосунок не може підключитися до сервера». Нижче цю проблему наведено як окрему типову помилку.
Крок 7: Зовнішні бібліотеки та завантажені файли, імпорт наявного дерева фотографій
Фотографії потрапляють до Immich двома способами. Це не одне й те саме.
- Завантажені файли — це об’єкти, якими керує Immich. Застосунок або вебзавантажувач копіює файл у
UPLOAD_LOCATION. Immich може перейменовувати, переміщувати та видаляти їх. - Зовнішні бібліотеки — це імпорт файлів у режимі лише для читання. Файли вже зберігаються в папці на сервері, у старому дереві
Picturesабо в експорті NAS. Immich індексує їх на місці та показує на часовій шкалі, але ніколи не змінює і не видаляє оригінали.
Щоб імпортувати наявне дерево, змонтуйте його в контейнер сервера в режимі лише для читання. Відредагуйте docker-compose.yml у immich-server: і додайте volume:
immich-server:
volumes:
- ${UPLOAD_LOCATION}:/data
- /etc/localtime:/etc/localtime:ro
- /srv/photos:/mnt/media/photos:ro:ro гарантує, що Immich не зможе змінити оригінали. Пересоздайте контейнер за допомогою sudo docker compose up -d. Потім у вебінтерфейсі відкрийте меню свого аватара → Administration → External Libraries → Create Library, виберіть користувача-власника, натисніть Add у розділі Folders і введіть шлях у контейнері — /mnt/media/photos, а не шлях на хості /srv/photos. Натисніть Scan. Використання шляху на хості замість шляху в контейнері — найпоширеніша помилка під час налаштування зовнішньої бібліотеки: сканування не знаходить файлів і повідомляє про нуль об’єктів.
Крок 8: Дисципліна оновлення, якої потребує Immich
Це етап, який визначає, чи працюватиме Immich стабільно, чи буде зламаний. Immich випускає оновлення швидко й не переносить виправлення до старих версій та не підтримує відкат. Якщо бездумно використовувати плаваючий тег v3, зрештою це призведе до пошкодження бази даних. Такий самий підхід із фіксацією версії та читанням приміток до випуску варто застосовувати до кожного довготривалого контейнера на сервері. Саме тому агент self-hosted KiroCrew фіксують на одному перевіреному тегу, а не дозволяють йому непередбачувано оновитися під час наступного перезапуску. Дотримуйтеся таких правил:
- Зафіксуйте версію. Задайте в
IMMICH_VERSIONконкретний тег, наприкладv3.0.2, а не плаваючийv3, який завжди завантажує найновішу версію v3.x. - Щоразу перед оновленням читайте примітки до випуску. У них зазначено критичні зміни, особливо зміни бази даних або vector extension. Випуск v3.0 є очевидним прикладом: у ньому повністю вилучили pgvecto.rs. Тому користувачі старого extension мали завершити міграцію на VectorChord, яку запровадили ще у v1.133, перш ніж переходити на новішу версію.
- Спочатку створіть резервну копію бази даних (Крок 9). Робіть це завжди, а якщо в примітках згадано базу даних — тим більше.
- Також завантажте новий compose-файл.
IMMICH_VERSIONфіксує лише образи сервера та ML. Образ Postgres зафіксований за digest усерединіdocker-compose.yml, тому для версії, якій потрібен новіший database extension, випускають новий compose-файл. Повторно завантажте обидва артефакти випуску, знову застосуйте значення.env, а потім виконайте оновлення. - Приблизно одночасно оновіть мобільні клієнти. Сервер підтримує лише відповідну йому major version, а застосунок підтримує поточну та попередню major version. Якщо сервер уже випередив версію застосунку, на телефоні відображатиметься
Your app major version is not compatible with the server!, доки ви не оновите застосунок. Тому найбезпечніше спочатку оновити застосунок.
Фактичні команди після розміщення нових файлів:
cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image pruneКрок 9: Резервні копії, дамп бази даних І оригінали, а також перевірка
Резервна копія Immich складається з двох частин, і без будь-якої з них інша втрачає сенс. База даних містить структуру альбомів, дані про обличчя, пошукові індекси та відповідність між ресурсом і файлом. Каталог оригіналів містить самі фотографії. Відновлення лише однієї частини дасть або фотографії без організації, або порожню структуру з посиланнями на відсутні файли.
Створіть дамп бази даних за допомогою pg_dump всередині контейнера Postgres. Дампуйте саме базу immich, а не весь кластер:
sudo docker exec -t immich_postgres pg_dump --clean --if-exists \
--dbname=immich --username=postgres | gzip > /opt/immich/immich-db-$(date +%F).sql.gzПотім створіть резервну копію UPLOAD_LOCATION — усього дерева /opt/immich/library, особливо його підкаталогів library/, upload/ і profile/ — за допомогою restic, rsync або borg на інший комп’ютер чи в об’єктне сховище. Спочатку копіюйте базу даних, а потім файли. Так дамп не міститиме посилань на фотографії, які резервна копія файлів ще не встигла скопіювати. Зовнішні бібліотеки резервуйте окремо з їхнього фактичного джерела. Immich ними не керує.
Тепер частина, яку часто пропускають: перевірте відновлення. Відновлення потрібно виконувати у новому стеку, сервер якого ще жодного разу не запускався, на образі Postgres із сумісним із дампом векторним розширенням. Саме тому не можна довільно змінювати тег образу DB. На тестовому сервері з тією самою конфігурацією compose і .env видаліть старий стан, запустіть лише базу даних, а потім завантажте дамп:
cd /opt/immich
sudo docker compose down -v
sudo docker compose pull
sudo docker compose create
sudo docker start immich_postgres
sleep 10
gunzip --stdout immich-db-2026-07-15.sql.gz |
sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" |
sudo docker exec -i immich_postgres psql --dbname=immich --username=postgres --single-transaction --set ON_ERROR_STOP=on
sudo docker compose up -dПеретворення search_path за допомогою sed є обов’язковим для бази даних VectorChord. Якщо пропустити цей крок, відновлення перерветься на півдорозі. Коли стек знову запрацює з вашими оригіналами, відкрийте вебінтерфейс. Якщо фотографії та альбоми на місці, резервна копія працює. Якщо ви ніколи цього не робили, у вас немає резервної копії — є лише надія.
Режими відмови та повідомлення, які ви побачите
Контейнер ML завершується через OOM-kill. sudo docker compose logs immich-machine-learning завершується аварійно, docker compose ps показує, що він Restarting, а код завершення — 137. sudo dmesg | grep -i oom підтверджує це повідомленням: Out of memory: Killed process ... (python3). Після цього завдання пошуку й розпізнавання облич зависають. Причина — недостатній обсяг RAM для моделей. Виконайте виправлення в такому порядку: додайте swap (Крок 1); збільште обсяг RAM у VPS; або, якщо це справді неможливо, вимкніть ML у Administration → Settings → Machine Learning Settings, вимкнувши Smart Search і Facial Recognition. Резервні копії та альбоми збережуться, але пошук за вмістом буде недоступний. Видалення сервісу immich-machine-learning з compose-файлу має такий самий ефект.
Postgres відмовляється запускатися після оновлення. У журналі сервера повторюється рядок на кшталт The database currently has VectorChord 0.5.3 activated, but the Postgres instance only has 0.4.2 available. This most likely means the extension was downgraded. або, у старіших стеках, The pgvecto.rs extension is not available in this Postgres instance.. Причина — образ бази даних із версією розширення, старішою за версію, до якої було оновлено ваші дані. Майже завжди це стається через ручне редагування тегу образу або відновлення новішого дампа на старішому образі. Використайте сумісний образ Postgres, візьміть compose-файл із релізу, що відповідає вашій базі даних, не виконуйте downgrade і відновлюйте дані лише на сумісний образ.
Мобільний застосунок не може підключитися до сервера. Після введення URL на екрані входу з’являється помилка підключення або Server is not reachable. Можливі три причини: ви ввели http://, хоча проксі обслуговує лише https://; ви підключилися безпосередньо до бекенду, але не вказали порт, тому застосунок спробував використати example.com (порт 443) замість example.com:2283; або reverse proxy не пересилає /api. Введіть повний URL https://photos.example.com і спочатку перевірте його відкриття в браузері на телефоні. Якщо в браузері URL відкривається, а в застосунку — ні, проксі видаляє шлях або сертифікат є self-signed, тому застосунок відхиляє недовірені сертифікати.
На диску закінчилося місце під час імпорту. Завантаження починають завершуватися помилками, ескізи стають порожніми, а в журналах з’являється ENOSPC: no space left on device або, для Postgres, could not extend file ... No space left on device. df -h показує, що том UPLOAD_LOCATION заповнений на 100%. Саме тому обсяг диска потрібно розрахувати до імпорту великої бібліотеки. Для відновлення підключіть том більшого розміру, зупиніть стек, перемістіть на нього UPLOAD_LOCATION, оновіть .env і запустіть стек знову. Також можна збільшити наявний диск, якщо це підтримує ваш провайдер. Postgres може зависнути після повного заповнення диска, тому звільніть місце та перезапустіть контейнер бази даних, перш ніж робити висновок про пошкодження даних.
FAQ
Скільки RAM і дискового простору потрібно Immich?
Офіційні вимоги Immich — щонайменше 6 GB RAM і рекомендовано 8 GB; 4 GB зі swap — практичний мінімум для невеликої бібліотеки. У будь-якому разі налаштуйте swap, оскільки саме контейнер машинного навчання створює пікове навантаження. Для диска закладіть повний розмір бібліотеки плюс приблизно 10–20% на згенеровані мініатюри та попередні перегляди. Використовуйте локальне сховище; ніколи не розміщуйте каталог даних Postgres на мережевій спільній папці. Якщо ви ще вирішуєте, які сервіси запускати, у посібнику про те, що розміщувати на власному сервері у 2026 році розмір Immich порівнюється з іншими сервісами.
Чи можна запускати Immich без GPU?
Так. Контейнер машинного навчання працює на CPU, а GPU лише прискорює індексацію для розумного пошуку та, у разі використання відповідного варіанта образу, транскодування відео. На CPU початкова індексація великої бібліотеки може тривати кілька годин у фоновому режимі, але не блокує резервне копіювання або перегляд. Якщо ваш сервер замалий для машинного навчання, у налаштуваннях адміністратора можна вимкнути Smart Search і Facial Recognition, залишивши всі інші функції.
Як безпечно оновити Immich?
Зафіксуйте IMMICH_VERSION на конкретному тегу, наприклад v3.0.2, перед кожним оновленням прочитайте примітки до релізу та спочатку створіть резервну копію бази даних. Оскільки образ Postgres зафіксований усередині docker-compose.yml, а не через IMMICH_VERSION, повторно завантажте файл compose і example.env з цільового релізу, повторно застосуйте власні значення, а потім виконайте docker compose pull && docker compose up -d. Ніколи не залишайте версію неконтрольованою для автоматичного оновлення: Immich випускає несумісні зміни й не підтримує пониження версії.
Що саме потрібно резервно копіювати?
Два компоненти разом: pg_dump бази даних immich і весь каталог оригіналів UPLOAD_LOCATION. У базі даних зберігаються альбоми, обличчя та відповідність ресурсів файлам; у каталозі — самі фотографії. Для відновлення потрібні обидва компоненти, а також образ бази даних із сумісним векторним розширенням. Спочатку створіть дамп бази даних, а потім скопіюйте файли. Принаймні один раз перевірте відновлення на тестовому сервері: резервна копія, яку не перевіряли, не є резервною копією.
Як імпортувати наявну папку з фотографіями?
Підключіть папку в режимі лише читання до контейнера immich-server як додатковий том, наприклад - /srv/photos:/mnt/media/photos:ro, повторно створіть контейнер, а потім у Administration → External Libraries створіть бібліотеку та додайте шлях у container /mnt/media/photos. Immich індексує файли на місці й не змінює та не видаляє їх. Найпоширеніша помилка — вказати шлях на хості замість шляху в контейнері, через що сканування не знаходить файлів.