SSD Nodes Learn Hosting plans →
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-28

راهنمای نصب Immich با 6 گیگابایت رم و مدیریت آپدیت‌ها

برای اجرای بهینه Immich با 6 گیگابایت رم، خطای exit 137 را مدیریت کنید. این راهنما نحوه تنظیم پورت 2283 روی HTTPS و رفع مشکل عدم اجرای نسخه v3 با pgvecto.rs را شرح می‌دهد.

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

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

نصب این سرویس شامل چهار کانتینر از فایل Docker Compose خود پروژه است. این بخش حدود 10 دقیقه زمان می‌برد. باقی این راهنما به بخش‌های چالش‌برانگیز اختصاص دارد: کانتینر یادگیری ماشین در سرورهای کوچک رم زیادی مصرف می‌کند، فایل‌های اصلی به‌سرعت فضای دیسک را پر می‌کنند، اپلیکیشن موبایل از اتصال به سرورهای فاقد 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های کوچک، کشته شدن container مربوط به ML توسط سیستم به دلیل کمبود حافظه (OOM-killed) است. ابتدا فضایی برای تنفس هسته سیستم‌عامل فراهم کنید.

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 نمی‌شود، اما از متوقف شدن container در حین ایندکس‌گذاری روی یک ماشین 4 گیگابایتی جلوگیری می‌کند.

گام 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 termination را همان‌جا انجام دهید. اگر از قبل چند container اجرا می‌کنید، Traefik با TLS خودکار برای چند اپلیکیشن Docker مرتب‌ترین گزینه است؛ یک بلوک label، درخواست‌های photos.example.com را به container مربوط به immich-server هدایت می‌کند و گواهی را نیز برای شما دریافت می‌کند. اگر nginx را ترجیح می‌دهید، راهنمای Let's Encrypt با Certbot و nginx گواهی و یک بلوک proxy_pass http://127.0.0.1:2283; در اختیار شما می‌گذارد. پس از ایجاد این proxy، افزودن سرویس بعدی عمدتاً به ساختن یک زیردامنه جدید نیاز دارد. به همین دلیل، یک front end رسانه‌ای مانند Halcyon، پوسته فروشگاه ویدئویی دهه 90 برای Jellyfin می‌تواند در همان سرور کنار Immich اجرا شود. همین موضوع درباره HarnessRouter با میزبانی شخصی برای قرار دادن Codex و Claude Code پشت یک API نیز صدق می‌کند. این سرویس عمداً به loopback متصل می‌شود و فقط پس از آن‌که proxy در جلوی آن TLS termination انجام دهد، قابل دسترسی خواهد بود. بنابراین، پیش از اختصاص‌دادن یک زیردامنه به آن، login پیش‌فرضش را تغییر دهید. البته هر container به یک hostname عمومی نیاز ندارد. بهتر است ابزار مخصوص مدیر، مانند اسکنر امنیتی open-kritt با میزبانی شخصی، اصلاً پشت proxy قرار نگیرد و فقط در موارد نادری که UI آن را باز می‌کنید، از طریق یک تونل SSH به آن دسترسی داشته باشید. برخی سرویس‌ها نیز proxy را کنار می‌گذارند، چون اساساً با HTTP کار نمی‌کنند. سرور relay با میزبانی شخصی RustDesk روشن‌ترین نمونه است. این سرویس روی چند پورت خام TCP و UDP گوش می‌دهد و به firewall rule نیاز دارد، نه زیردامنه. یک تنظیم proxy برای Immich اهمیت دارد: limit اندازه upload را افزایش دهید، چون ویدئوهای تلفن همراه حجیم هستند. در nginx، این تنظیم client_max_body_size 50000M; را داخل server block قرار دهید؛ مقدار پیش‌فرض 1 MB، upload ویدئو را با 413 Request Entity Too Large رد می‌کند.

قانونی که اپلیکیشن اعمال می‌کند این است: endpoint باید در دسترس باشد و در عمل، حتماً باید HTTPS باشد. endpointهای http:// یا استفاده از 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) نمی‌کند و از دانگرید پشتیبانی نمی‌کند. دنبال کردن کورکورانه تگ شناور v3 در نهایت باعث خرابی دیتابیس شما خواهد شد. عادت «ابتدا پین کردن و سپس خواندن یادداشت‌ها» برای هر کانتینر با عمر طولانی روی سرور شما ارزشمند است؛ به همین دلیل است که یک agent از KiroCrew در حالت self-hosted به یک تگ مشخص و تست‌شده پین می‌شود تا در ری‌استارت بعدی، نسخه آن بدون اطلاع شما تغییر نکند. این نظم شامل موارد زیر است:

  1. پین کردن نسخه: مقدار IMMICH_VERSION را روی یک تگ مشخص مانند v3.0.2 تنظیم کنید، نه تگ شناور v3 که همیشه جدیدترین نسخه v3.x را دریافت می‌کند.
  2. خواندن یادداشت‌های انتشار (release notes) در هر بار ارتقا: پیش از ارتقا، حتماً یادداشت‌ها را بخوانید. تغییرات ساختاری (breaking changes)، به‌ویژه تغییرات دیتابیس یا افزونه‌های برداری (vector-extension)، در آنجا ذکر می‌شوند. انتشار v3.0 مثال بارزی است: این نسخه pgvecto.rs را به‌طور کامل حذف کرد، بنابراین هر کسی که هنوز از افزونه قدیمی استفاده می‌کرد، باید پیش از ارتقا، مهاجرت به VectorChord (که در v1.133 معرفی شده بود) را تکمیل می‌کرد.
  3. تهیه نسخه پشتیبان از دیتابیس (گام 9): همیشه این کار را انجام دهید، اما زمانی که یادداشت‌ها به دیتابیس اشاره دارند، اهمیت آن دوچندان می‌شود.
  4. دریافت فایل compose جدید: مقدار IMMICH_VERSION فقط ایمیج‌های server و ML را پین می‌کند. ایمیج Postgres توسط digest در داخل docker-compose.yml پین شده است، بنابراین نسخه‌ای که به افزونه دیتابیس جدیدتری نیاز دارد، فایل compose جدیدی ارائه می‌دهد. هر دو فایل منتشر شده را دوباره دانلود کنید، مقادیر .env خود را مجدداً اعمال کنید و سپس ارتقا دهید.
  5. به‌روزرسانی کلاینت‌های موبایل در همان بازه زمانی: سرور فقط با نسخه اصلی (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: پشتیبان‌گیری، تهیه 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)؛ یا اگر واقعاً امکان افزایش منابع ندارید، 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. نمایش داده می‌شود. علت این مشکل استفاده از image دیتابیسی است که نسخه extension آن قدیمی‌تر از نسخه‌ای است که داده‌های شما به آن ارتقا یافته‌اند؛ این اتفاق معمولاً در اثر تغییر دستی تگ image یا بازگردانی dump جدیدتر روی یک image قدیمی رخ می‌دهد. راه‌حل این است که از image منطبق با Postgres استفاده کنید، فایل compose مربوط به همان نسخه‌ای که دیتابیس شما با آن سازگار است را به کار ببرید، از دانگرید کردن خودداری کنید و فقط روی یک image سازگار، داده‌ها را بازگردانی کنید.

اپلیکیشن موبایل نمی‌تواند به سرور متصل شود. پس از وارد کردن URL، صفحه ورود خطای اتصال یا Server is not reachable را نشان می‌دهد. سه علت احتمالی وجود دارد: شما http:// را وارد کرده‌اید در حالی که پروکسی فقط https:// را سرویس‌دهی می‌کند؛ شما مستقیماً به backend متصل شده‌اید اما پورت را وارد نکرده‌اید، بنابراین تلاش کرده است به example.com (پورت 443) متصل شود به جای example.com:2283؛ یا reverse proxy در حال forward کردن /api نیست. برای رفع مشکل، URL کامل https://photos.example.com را وارد کنید و ابتدا در مرورگر گوشی بررسی کنید که بارگذاری می‌شود یا خیر. اگر مرورگر کار می‌کند اما اپلیکیشن نه، احتمالاً پروکسی مسیر (path) را حذف می‌کند یا گواهی‌نامه خودامضا (self-signed) است؛ اپلیکیشن گواهی‌های غیرمعتبر را رد می‌کند.

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

FAQ

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

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

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

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

چگونه 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 تغییرات ساختاری (breaking changes) ارائه می‌دهد و از دانگرید (downgrade) پشتیبانی نمی‌کند.

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

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

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

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