SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor

Immich خودمیزبانی: 6 GB RAM و ارتقای امن

عدد واقعی RAM، تنظیم پورت 2283 پشت HTTPS، خطای دقیق exit 137 و ناسازگاری Immich v3 با پایگاه‌داده pgvecto.rs را ببینید؛ مراحل بازیابی هم ارائه شده است.

آنچه در حال ساخت آن هستید

Immich یک سرویس خودمیزبان (self-hosted) برای پشتیبان‌گیری از عکس و ویدیو است که جایگزینی واقعی برای Google Photos محسوب می‌شود. این سرویس دارای یک اپلیکیشن موبایل است که در پس‌زمینه از گالری دوربین شما نسخه پشتیبان تهیه می‌کند و قابلیت‌هایی نظیر تایم‌لاین، آلبوم‌ها، تشخیص چهره و جستجوی مبتنی بر یادگیری ماشین دارد که می‌تواند بدون نیاز به تگ‌گذاری دستی، مواردی مانند «ساحل» یا چهره افراد را پیدا کند. شما این سرویس را روی VPS شخصی خود اجرا می‌کنید؛ فایل‌های اصلی روی دیسک شما باقی می‌مانند و هیچ‌کس آن‌ها را برای تبلیغات اسکن نمی‌کند. اگر هنوز در حال مقایسه آن با گزینه مطرح دیگر هستید، مقایسه ما بین PhotoPrism و Immich حداقل میزان RAM مورد نیاز، اپلیکیشن‌های موبایل و دستورات پشتیبان‌گیری آن‌ها را در کنار هم قرار داده است.

نصب این سرویس شامل چهار کانتینر از فایل Docker Compose خود پروژه است. این بخش حدود ده دقیقه زمان می‌برد. باقی این راهنما به بخش‌های چالش‌برانگیز اختصاص دارد: کانتینر یادگیری ماشین در سرورهای کوچک حافظه زیادی مصرف می‌کند، فایل‌های اصلی به‌سرعت فضا را پر می‌کنند، اپلیکیشن موبایل به URL دقیق سرور نیاز دارد و شما پیش از خروج از شبکه داخلی، به HTTPS در مقابل آن نیاز دارید. همچنین Immich به‌طور مرتب تغییرات ساختاری (breaking changes) ارائه می‌دهد که یک docker compose pull بی‌دقت می‌تواند باعث شود سرور شما دیگر بالا نیاید. این چهار مورد را جدی بگیرید تا Immich برایتان کاملاً پایدار بماند؛ در غیر این صورت، ممکن است کل آخر هفته خود را صرف عیب‌یابی کنید.

پیش‌نیازها و نکات مهم

  • حافظه رم: مستندات رسمی حداقل 6 گیگابایت و مقدار پیشنهادی 8 گیگابایت را ذکر کرده‌اند، اما 4 گیگابایت به همراه swap را به عنوان کف مطلق در نظر بگیرید. کانتینرهای immich-server و Postgres سبک هستند. کانتینر immich-machine-learning پرمصرف‌ترین بخش است؛ این کانتینر مدل‌های CLIP و تشخیص چهره را برای ساخت ایندکس‌های جستجو در رم بارگذاری می‌کند و در یک سرور 2 گیگابایتی، هسته سیستم‌عامل آن را متوقف (kill) می‌کند. حتی اگر 4 گیگابایت رم دارید، حتماً swap اضافه کنید.
  • دیسک: ظرفیت را بر اساس کل کتابخانه خود و مقداری فضای اضافه در نظر بگیرید. فایل‌های اصلی شما به‌طور کامل کپی می‌شوند و Immich نیز تصاویر بندانگشتی (thumbnails) و پیش‌نمایش تولید می‌کند (حدود 10 تا 20 درصد فضای بیشتر). برای یک مجموعه عکس 200 گیگابایتی، به یک volume با ظرفیت 300 گیگابایت نیاز دارید. Postgres در مقایسه با این حجم، بسیار کوچک است.
  • پردازنده: هر VPS مدرن مبتنی بر KVM مناسب است، اما پردازش یادگیری ماشین (ML) روی CPU کند است. ایندکس‌گذاری هوشمند برای یک واردات (import) بزرگ ممکن است ساعت‌ها در پس‌زمینه طول بکشد. این موضوع طبیعی است و نیازی به GPU ندارد.
  • یک نام دامنه که به VPS اشاره کند. اپلیکیشن موبایل به‌شدت استفاده از HTTPS را ترجیح می‌دهد و شما به یک reverse proxy در مقابل آن نیاز دارید. ساختار این تنظیمات مشابه میزبانی شخصی Nextcloud با Docker، TLS و پشتیبان‌گیری است؛ Immich در واقع همتای مدیریت عکس برای آن سرور فایل محسوب می‌شود.
  • Docker و پلاگین Compose: نصب Docker Engine به همراه پلاگین Compose v2 از مخزن رسمی apt شرکت Docker، دقیقاً مطابق با آنچه در راهنمای مقدماتی Docker Compose ما پوشش داده شده است.

گام 1: پیش از هر کاری swap اضافه کنید

شایع‌ترین دلیل شکست Immich در یک VPS کوچک، کشته شدن (OOM-killed) کانتینر ML به دلیل کمبود حافظه است. ابتدا فضایی برای تنفس هسته سیستم‌عامل فراهم کنید.

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 نسخه‌های سرویس و به‌طور حیاتی، ایمیج دیتابیس خود را درون فایل‌هایی که منتشر می‌کند، ثابت (pin) کرده است. یک فایل 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

این فایل‌ها از نسخه تگ‌شده (tagged release) می‌آیند، بنابراین ارجاعات ایمیج با هم مطابقت دارند. فایل 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 و تشخیص چهره. مدل‌های دانلودشده را در یک volume به نام model-cache کش می‌کند. این سرویس بیشترین مصرف حافظه را دارد.
  • database (کانتینر immich_postgres)، دیتابیس Postgres به همراه افزونه برداری VectorChord که قدرت جستجوی شباهت را فراهم می‌کند. تگ ایمیج مستقیماً در فایل compose با استفاده از digest ثابت شده است، برای مثال ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:.... تنظیمات قدیمی‌تر از pgvecto.rs استفاده می‌کردند؛ پشتیبانی از آن در Immich v3.0 حذف شد، بنابراین هر چیزی که امروز نصب می‌کنید VectorChord است. هرگز این تگ را به صورت دستی ویرایش نکنید.
  • redis (کانتینر immich_redis)، یک نمونه Valkey/Redis برای صف‌های پردازش (job queues).

گام 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 باید به دیسک بزرگ شما اشاره کند؛ اگر بعداً یک volume داده متصل کردید، از همان ابتدا آن را روی مسیر mount مربوطه تنظیم کنید، زیرا جابه‌جایی آن پس از راه‌اندازی، مستلزم انتقال تصاویر بندانگشتی (thumbnails) و به‌روزرسانی مسیرهای دارایی‌ها (asset paths) است. همچنین DB_DATA_LOCATION باید روی دیسک محلی باشد: اجرای Postgres روی اشتراک‌های NFS یا SMB باعث خرابی داده می‌شود و مستندات صراحتاً به این موضوع اشاره کرده‌اند. اگر در DB_PASSWORD فقط از حروف و اعداد استفاده کنید، از دسته‌ای از باگ‌های مربوط به escape کردن رشته‌های اتصال (connection-string) جلوگیری خواهید کرد.

گام 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) را نمایش می‌دهد؛ اولین حسابی که ایجاد می‌کنید، حساب مدیر (admin) است. یک رمز عبور قوی انتخاب کنید؛ این حساب مالک تنظیمات سرور، مدیریت کاربران و پیکربندی ML است که بعداً به آن نیاز خواهید داشت.

گام 5: اپلیکیشن موبایل و پشتیبان‌گیری در پس‌زمینه

اپلیکیشن Immich را از App Store یا Play Store نصب کنید. در صفحه ورود، از شما یک Server Endpoint URL خواسته می‌شود. آدرس کامل شامل طرح (scheme) را وارد کنید، برای مثال https://photos.example.com (اپلیکیشن به‌طور خودکار /api را به انتهای آن اضافه می‌کند). با حسابی که به‌تازگی ساخته‌اید وارد شوید، سپس صفحه Backup در اپلیکیشن را باز کنید، آلبوم‌هایی که می‌خواهید از آن‌ها محافظت شود (معمولاً Camera و Screenshots) را انتخاب کرده و Background backup را فعال کنید. پشتیبان‌گیری در پس‌زمینه در iOS توسط سیستم‌عامل محدود می‌شود؛ آپلودها در حالت پیش‌زمینه همیشه اجرا می‌شوند، اما آپلودهای پس‌زمینه تنها زمانی انجام می‌گیرند که سیستم‌عامل اجازه دهد.

این دقیقاً همان مرحله‌ای است که کاربران در آن دچار مشکل می‌شوند، بنابراین پیش از آنکه با اپلیکیشن کلنجار بروید، گام 6 را مطالعه کنید.

گام 6: استفاده از HTTPS از طریق reverse proxy و قانون URL کامل

اپلیکیشن موبایل پس از خروج از شبکه خانگی شما، حتماً به HTTPS نیاز دارد. یک reverse proxy جلوی پورت 2283 قرار دهید و TLS را در همان‌جا terminate کنید. اگر در حال حاضر چندین کانتینر را اجرا می‌کنید، Traefik با TLS خودکار برای چندین اپلیکیشن Docker مرتب‌ترین گزینه است؛ یک بلوک label ترافیک photos.example.com را به کانتینر immich-server هدایت کرده و گواهی را برای شما دریافت می‌کند. اگر nginx را ترجیح می‌دهید، راهنمای Let's Encrypt با Certbot و nginx به شما یک گواهی و یک بلوک proxy_pass http://127.0.0.1:2283; می‌دهد. هنگامی که این پروکسی ایجاد شد، افزودن سرویس بعدی عمدتاً شامل یک زیردامنه جدید است؛ به همین دلیل است که یک رابط کاربری رسانه‌ای مانند Halcyon، پوسته فروشگاه ویدیوی دهه 90 برای Jellyfin در کنار Immich روی همان سرور قرار می‌گیرد. همین موضوع در مورد یک HarnessRouter خودمیزبان که Codex و Claude Code را پشت یک API قرار می‌دهد نیز صادق است؛ این سرویس عمداً به loopback متصل می‌شود و تنها زمانی قابل دسترسی است که پروکسی، TLS را در مقابل آن terminate کند، بنابراین پیش از اختصاص زیردامنه، نام کاربری پیش‌فرض آن را تغییر دهید. البته هر کانتینری نیازی به hostname عمومی ندارد: ابزارهای صرفاً مدیریتی مانند یک اسکنر امنیتی open-kritt خودمیزبان بهتر است کاملاً از پروکسی دور بمانند و در موارد نادری که به رابط کاربری آن نیاز دارید، از طریق SSH tunnel به آن دسترسی پیدا کنید. برخی سرویس‌های دیگر پروکسی را نادیده می‌گیرند زیرا زبان آن‌ها اصلاً HTTP نیست؛ یک سرور relay خودمیزبان RustDesk واضح‌ترین مثال است که روی تعدادی پورت خام TCP و UDP گوش می‌دهد و به جای زیردامنه، به قوانین فایروال نیاز دارد. یک تنظیم پروکسی برای Immich اهمیت دارد: محدودیت حجم آپلود را افزایش دهید، زیرا ویدیوهای گوشی حجیم هستند. در nginx این مقدار client_max_body_size 50000M; در داخل بلوک server است؛ مقدار پیش‌فرض 1 MB آپلود ویدیوها را با خطای 413 Request Entity Too Large رد می‌کند. اگر پروکسی شما به چالش‌های HTTP-01 مربوط به Let's Encrypt نیز پاسخ می‌دهد، مطمئن شوید که /.well-known/immich همچنان به Immich هدایت می‌شود و نه به هندلر چالش.

قانونی که اپلیکیشن اعمال می‌کند این است: endpoint باید دقیقاً در همان URL که تایپ می‌کنید در دسترس باشد. اپلیکیشن یک http://YOUR_SERVER_IP:2283 ساده را می‌پذیرد (راهنمای ورود خودِ اپلیکیشن http://your-server-ip:port است)، اما هر چیزی که از اینترنت عبور می‌کند باید HTTPS باشد. طرح (scheme) اشتباه یا استفاده از IP مستقیم بدون پورت، همان جایی است که خطای "اپلیکیشن نمی‌تواند به سرور متصل شود" از آن ناشی می‌شود که در ادامه به عنوان یک خطای نام‌گذاری‌شده بررسی شده است.

گام 7: کتابخانه‌های خارجی در مقابل آپلودها، وارد کردن یک ساختار عکس موجود

دو روش برای انتقال عکس‌ها به Immich وجود دارد که با یکدیگر متفاوت هستند.

  • آپلودها (Uploads) دارایی‌هایی هستند که مالکیت آن‌ها با Immich است. اپلیکیشن یا آپلودر وب، فایل را در UPLOAD_LOCATION کپی می‌کند. Immich می‌تواند آن‌ها را تغییر نام دهد، جابه‌جا کند یا حذف نماید.
  • کتابخانه‌های خارجی (External libraries) وارداتِ فقط‌خواندنی (read-only) از فایل‌هایی هستند که از قبل در پوشه‌ای روی سرور شما، یک ساختار قدیمی Pictures یا یک خروجی NAS قرار دارند. Immich آن‌ها را در همان محل ایندکس کرده و در تایم‌لاین نمایش می‌دهد، اما هرگز فایل‌های اصلی را تغییر نمی‌دهد یا حذف نمی‌کند.

برای وارد کردن یک ساختار موجود، آن را به‌صورت فقط‌خواندنی در container سرور mount کنید. فایل 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 هرگز نمی‌تواند به فایل‌های اصلی دسترسی داشته باشد. container را با دستور sudo docker compose up -d دوباره ایجاد کنید، سپس در رابط کاربری وب به آواتار خود بروید و مسیر Administration → External Libraries → Create Library را دنبال کنید. کاربر مالک را انتخاب کرده، در بخش Folders روی Add کلیک کنید و مسیر container یعنی /mnt/media/photos را وارد کنید، نه مسیر میزبان (host) یعنی /srv/photos. روی Scan کلیک کنید. استفاده از مسیر میزبان به‌جای مسیر container، رایج‌ترین اشتباه در تنظیم کتابخانه‌های خارجی است؛ در این حالت اسکن چیزی پیدا نمی‌کند و تعداد دارایی‌ها را صفر گزارش می‌دهد.

گام 8: انضباط ارتقا که Immich می‌طلبد

این بخشی است که تفاوت بین یک Immich سالم و یک Immich خراب را مشخص می‌کند. Immich با سرعت زیاد عرضه می‌شود، اصلاحات را به نسخه‌های قدیمی‌تر backport نمی‌کند و از دانگرید (downgrade) پشتیبانی نمی‌کند. تگ شناور v3 روشی است که به‌طور رسمی برای دنبال کردن نسخه‌ها پشتیبانی می‌شود و Immich تلاش می‌کند تغییرات ساختارشکن (breaking changes) را به نسخه‌های اصلی (major versions) محدود کند، اما با هر بار pull کردن، شما را ارتقا می‌دهد؛ فارغ از اینکه یادداشت‌های انتشار را خوانده باشید یا خیر. ارتقایی که برای آن برنامه‌ریزی نکرده باشید، قابل بازگشت نیست. عادتِ «ابتدا پین کردن و سپس خواندن یادداشت‌ها» برای هر کانتینر طولانی‌مدت روی سرور شما ارزشمند است؛ به همین دلیل است که یک agent خودمیزبان KiroCrew به یک تگ مشخص و تست‌شده پین می‌شود تا در ری‌استارت بعدی، نسخه آن بدون اطلاع شما تغییر نکند. انضباط لازم به شرح زیر است:

  1. یک نسخه را پین کنید. مقدار IMMICH_VERSION را روی یک تگ مشخص مانند v3.0.2 تنظیم کنید، نه روی تگ شناور v3 که همیشه جدیدترین نسخه v3.x را دریافت می‌کند.
  2. هر بار پیش از ارتقا، یادداشت‌های انتشار را بخوانید. تغییرات ساختارشکن، به‌ویژه تغییرات دیتابیس یا vector-extension، در آنجا ذکر می‌شوند. انتشار v3.0 مثال بارزی است: این نسخه pgvecto.rs را به‌طور کامل حذف کرد، بنابراین هر کسی که هنوز از extension قدیمی استفاده می‌کرد، باید پیش از ارتقا، مهاجرت VectorChord (که در v1.133 معرفی شده بود) را به پایان می‌رساند.
  3. ابتدا از دیتابیس بک‌آپ بگیرید (گام 9). همیشه این کار را انجام دهید، اما زمانی که یادداشت‌ها به دیتابیس اشاره دارند، این کار را دوچندان جدی بگیرید.
  4. فایل compose جدید را نیز دریافت کنید. مقدار IMMICH_VERSION فقط ایمیج‌های server و ML را پین می‌کند. ایمیج Postgres توسط digest درون docker-compose.yml پین شده است، بنابراین نسخه‌ای که به extension جدیدتری برای دیتابیس نیاز دارد، فایل compose جدیدی به همراه دارد. هر دو فایل انتشار را مجدداً دانلود کنید، مقادیر .env خود را دوباره اعمال کنید و سپس ارتقا دهید.
  5. ابتدا کلاینت‌های موبایل خود را به‌روزرسانی کنید. سرور فقط با نسخه اصلی (major) منطبق با خود ارتباط برقرار می‌کند و اپلیکیشن معمولاً با نسخه اصلی فعلی و قبلی سازگار است. هنگامی که سرور جدیدتر از اپلیکیشن باشد، نسخه‌های فعلی (v3.3.1، بررسی‌شده در 2026-10-10) یک اعلان با عنوان App update is available به همراه دکمه Update روی گوشی نمایش می‌دهند و Immich توصیه می‌کند پیش از ارتقای سرور، تمام کلاینت‌های موبایل را به‌روزرسانی کنید.

دستورات اجرایی، پس از جایگزینی فایل‌های جدید:

cd /opt/immich
sudo docker compose pull
sudo docker compose up -d
sudo docker image prune

گام 9: پشتیبان‌گیری، تهیه dump از پایگاه داده به همراه فایل‌های اصلی، و تست آن

پشتیبان‌گیری از Immich شامل دو بخش است و داشتن یکی بدون دیگری بی‌فایده است. پایگاه داده ساختار آلبوم‌ها، چهره‌ها، نمایه‌های جستجو و نگاشت بین دارایی‌ها و فایل‌ها را در خود نگه می‌دارد. دایرکتوری originals شامل خود عکس‌هاست. اگر یکی را بدون دیگری بازیابی کنید، یا عکس‌هایی بدون سازمان‌دهی خواهید داشت یا یک پوسته خالی که به فایل‌های گمشده اشاره می‌کند. این ساختار دو‌بخشی مختص Immich نیست: یک میز پشتیبانی Chatwoot که خودتان میزبانی می‌کنید نیز به همین جفت‌سازی یعنی یک dump از Postgres و دایرکتوری uploads نیاز دارد، در غیر این صورت صندوق ورودی بازیابی‌شده با فقدان تمام پیوست‌ها مواجه خواهد شد. کپی کردن دایرکتوری داده‌های Postgres به صورت یک درخت فایل، میان‌بری برای مرحله dump به نظر می‌رسد اما یک پشتیبان قابل‌استفاده نیست؛ تله‌ای که راهنمای کامل پشتیبان‌گیری و بازیابی 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 به یک ماشین دیگر یا فضای ذخیره‌سازی شیء (object storage) پشتیبان تهیه کنید. هر زمان‌بندی که این کار را انجام می‌دهد، چه یک ورودی cron باشد یا یک systemd timer، باید جایی برای اعلام خطا در صورت شکست داشته باشد؛ یک واحد OnFailure= در systemd که به سرور ntfy شخصی شما اشاره می‌کند، در شب خرابی dump پیامی را روی گوشی شما می‌فرستد تا مجبور نباشید هنگام بازیابی متوجه آن شوید. ابتدا پایگاه داده و سپس فایل‌ها را پشتیبان بگیرید تا dump هرگز به عکسی که هنوز توسط پشتیبان‌گیری فایل کپی نشده است، ارجاع ندهد. از کتابخانه‌های خارجی به‌طور جداگانه در منبع اصلی‌شان پشتیبان بگیرید؛ Immich مالک آن‌ها نیست.

حالا بخشی که همه از آن صرف‌نظر می‌کنند: تست بازیابی. بازیابی باید روی یک stack تازه اجرا شود که سرور آن هرگز شروع به کار نکرده است، روی یک image از Postgres که افزونه vector آن با dump سازگار باشد؛ دقیقاً به همین دلیل است که هرگز نباید تگ image پایگاه داده را به صورت بداهه تغییر دهید. روی یک سیستم تست با همان compose و .env، هرگونه وضعیت قدیمی را پاک کنید، فقط پایگاه داده را بالا بیاورید و سپس dump را بارگذاری کنید:

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

بازنویسی sed در search_path برای پایگاه داده VectorChord اختیاری نیست؛ اگر آن را حذف کنید، بازیابی در میانه راه متوقف می‌شود. وقتی stack با فایل‌های اصلی شما در جای خود بالا آمد، رابط کاربری وب را باز کنید: اگر عکس‌ها و آلبوم‌های شما آنجا هستند، پشتیبان شما کار می‌کند. اگر هرگز این کار را انجام نداده‌اید، شما پشتیبان ندارید، فقط امیدوارید که داشته باشید.

حالت‌های شکست و پیام‌های مربوطه

کانتینر ML به دلیل OOM-killed متوقف می‌شود. 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)؛ یا اگر واقعاً امکان افزایش RAM ندارید، به مسیر Administration → Settings → Machine Learning Settings بروید و سوییچ اصلی یادگیری ماشین را خاموش کنید که تمام قابلیت‌های ML را یک‌جا غیرفعال می‌کند. خاموش کردن فقط Smart Search و Facial Recognition کافی نیست، زیرا OCR و سایر انواع مدل‌ها به‌صورت پیش‌فرض فعال می‌مانند. در این حالت، شما بک‌آپ‌ها و آلبوم‌ها را حفظ می‌کنید، اما قابلیت جستجو بر اساس محتوا را از دست می‌دهید. حذف سرویس immich-machine-learning از فایل compose نیز همین نتیجه را دارد.

سرور Immich پس از ارتقا اجرا نمی‌شود. ممکن است کانتینر Postgres به‌خوبی کار کند؛ این immich_server است که نسخه افزونه vector را هنگام شروع بررسی کرده و از اجرا خودداری می‌کند. لاگ آن در یک حلقه با خطی مشابه 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. دیده می‌شود. علت این مشکل، استفاده از ایمیج دیتابیسی است که نسخه افزونه آن قدیمی‌تر از نسخه‌ای است که داده‌های شما به آن ارتقا یافته‌اند؛ این اتفاق معمولاً در اثر تغییر دستی تگ ایمیج یا بازگردانی یک dump جدیدتر روی یک ایمیج قدیمی رخ می‌دهد. راه‌حل این است که از ایمیج Postgres منطبق استفاده کنید، فایل compose مربوط به همان نسخه‌ای که دیتابیس شما با آن سازگار است را بردارید، از دانگرید کردن خودداری کنید و فقط روی ایمیج سازگار بازگردانی انجام دهید.

اپلیکیشن موبایل نمی‌تواند به سرور متصل شود. پس از وارد کردن URL، صفحه ورود خطایی مانند Could not connect to server را نشان می‌دهد. دلایل معمول عبارتند از: شما http:// را وارد کرده‌اید در حالی که پروکسی فقط https:// را سرویس می‌دهد؛ شما مستقیماً به بک‌اند متصل شده‌اید اما پورت را وارد نکرده‌اید، بنابراین تلاش کرده است به example.com (پورت 443) متصل شود به جای example.com:2283؛ reverse proxy در حال فوروارد کردن /api نیست؛ یا پروکسی که چالش‌های HTTP-01 مربوط به Let's Encrypt را مدیریت می‌کند، /.well-known/immich را به مقصدی غیر از Immich هدایت می‌کند. برای رفع مشکل، URL کامل https://photos.example.com را وارد کنید و ابتدا مطمئن شوید که در مرورگر گوشی بارگذاری می‌شود. اگر مرورگر کار می‌کند اما اپلیکیشن نه، پروکسی در حال حذف مسیر (path) یا مسیریابی اشتباه /.well-known/immich است، یا گواهی از نوع self-signed است که اپلیکیشن به دلیل خطای handshake آن را رد می‌کند، مگر اینکه در تنظیمات اپلیکیشن، پشتیبانی از گواهی‌های self-signed را فعال کنید.

کمبود فضای دیسک در حین وارد کردن (import) فایل‌ها. آپلودها با شکست مواجه می‌شوند، تصاویر بندانگشتی (thumbnails) خالی می‌مانند و لاگ‌ها ENOSPC: no space left on device یا از سمت Postgres، خطای could not extend file ... No space left on device را نشان می‌دهند. دستور df -h نشان می‌دهد که حجم UPLOAD_LOCATION صد در صد پر شده است. به همین دلیل است که باید پیش از وارد کردن یک کتابخانه بزرگ، فضای دیسک را متناسب‌سازی کنید. برای بازیابی، یک حجم (volume) بزرگ‌تر متصل کنید، استک را متوقف کنید، UPLOAD_LOCATION را به آن منتقل کنید، .env را به‌روزرسانی کرده و دوباره شروع کنید، یا اگر ارائه‌دهنده شما اجازه می‌دهد، دیسک فعلی را گسترش دهید. اگر دیسک پر شود، Postgres ممکن است قفل شود؛ بنابراین پیش از فرض کردن خرابی دیتابیس، فضا را خالی کرده و کانتینر دیتابیس را ری‌استارت کنید.

FAQ

Immich به چه مقدار RAM و فضای دیسک نیاز دارد؟

حداقل نیاز رسمی Immich برابر با 6 GB رم است و 8 GB توصیه می‌شود. 4 GB رم به همراه swap، کفِ عملیاتی برای یک کتابخانه کوچک است؛ در هر صورت swap را پیکربندی کنید، زیرا کانتینر یادگیری ماشین (machine-learning) بخشی است که مصرف آن ناگهان افزایش می‌یابد. برای دیسک، حجم کل کتابخانه خود را به اضافه حدود 10 تا 20 درصد برای تصاویر بندانگشتی (thumbnails) و پیش‌نمایش‌ها در نظر بگیرید. از ذخیره‌سازی محلی استفاده کنید و هرگز دایرکتوری داده‌های Postgres را روی network share قرار ندهید. اگر هنوز در حال تصمیم‌گیری برای اجرای سرویس‌های دیگر هستید، راهنمای سرویس‌های قابل میزبانی در سال 2026 ردپای منابع Immich را در کنار سایر سرویس‌ها نشان می‌دهد.

آیا می‌توانم Immich را بدون GPU اجرا کنم؟

بله. کانتینر یادگیری ماشین به‌خوبی روی CPU اجرا می‌شود؛ GPU فقط سرعت ایندکس‌گذاری جستجوی هوشمند و در صورت استفاده از variant مناسب تصویر، سرعت تبدیل ویدیو (transcoding) را افزایش می‌دهد. روی CPU، ایندکس اولیه یک کتابخانه بزرگ ممکن است ساعت‌ها در پس‌زمینه زمان ببرد، اما مانع از پشتیبان‌گیری یا مرور عکس‌ها نمی‌شود. اگر سخت‌افزار شما برای یادگیری ماشین بسیار ضعیف است، می‌توانید آن را به‌طور کامل از طریق گزینه موجود در تنظیمات مدیریت (admin settings) غیرفعال کنید و از سایر قابلیت‌ها استفاده کنید.

چگونه Immich را با امنیت ارتقا دهم؟

نسخه IMMICH_VERSION را روی یک تگ مشخص مانند v3.0.2 ثابت (pin) کنید، پیش از هر ارتقا یادداشت‌های انتشار (release notes) را بخوانید و ابتدا از دیتابیس پشتیبان تهیه کنید. از آنجا که ایمیج Postgres در داخل docker-compose.yml به جای IMMICH_VERSION ثابت شده است، هم فایل compose و هم example.env را از نسخه هدف دانلود کنید، مقادیر خود را مجدداً اعمال کنید و سپس docker compose pull && docker compose up -d را اجرا کنید. هرگز اجازه ندهید نسخه به‌صورت خودکار و بدون نظارت تغییر کند؛ Immich از دانگرید (downgrade) پشتیبانی نمی‌کند، بنابراین ارتقایی که درباره آن مطالعه نکرده‌اید، قابل بازگشت نیست.

دقیقاً از چه چیزی باید پشتیبان بگیرم؟

دو مورد با هم: یک pg_dump از دیتابیس immich و کل دایرکتوری originals در UPLOAD_LOCATION. دیتابیس شامل آلبوم‌ها، چهره‌ها و نگاشت دارایی به فایل است؛ دایرکتوری شامل خود عکس‌هاست. بازیابی (restore) به هر دو مورد به اضافه یک ایمیج دیتابیس با افزونه برداری (vector extension) سازگار نیاز دارد. ابتدا dump دیتابیس را بگیرید و سپس کپی فایل‌ها را انجام دهید. حداقل یک بار بازیابی را روی یک سیستم آزمایشی تست کنید؛ پشتیبانی که تست نشده باشد، پشتیبان نیست.

چگونه پوشه عکس‌های موجود خود را وارد کنم؟

پوشه را به‌صورت read-only در کانتینر immich-server به عنوان یک volume اضافی (برای مثال - /srv/photos:/mnt/media/photos:ro) mount کنید، کانتینر را دوباره بسازید، سپس در بخش Administration → External Libraries یک کتابخانه ایجاد کرده و مسیر کانتینر یعنی /mnt/media/photos را اضافه کنید. Immich فایل‌ها را در همان محل ایندکس می‌کند و هرگز آن‌ها را تغییر نمی‌دهد یا حذف نمی‌کند. رایج‌ترین اشتباه، وارد کردن مسیر میزبان (host path) به جای مسیر کانتینر است که باعث می‌شود اسکن چیزی پیدا نکند.