SSD Nodes Learn Hosting plans →
คู่มือ Matt Connorโดย Matt Connor

วิธีติดตั้ง Immich บน VPS ให้เสถียรและอัปเดตอย่างปลอดภัย

คู่มือการใช้งาน Immich บน VPS พร้อมวิธีแก้ปัญหาหน่วยความจำไม่พอจนเกิด exit 137 การตั้งค่า HTTPS ที่พอร์ต 2283 และข้อควรระวังเรื่อง pgvecto.rs เมื่ออัปเกรดเป็นเวอร์ชัน v3

สิ่งที่คุณกำลังสร้าง

Immich คือบริการสำรองข้อมูลรูปภาพและวิดีโอแบบ self-hosted ซึ่งเป็นตัวเลือกทดแทน Google Photos ได้อย่างแท้จริง โดยมีแอปพลิเคชันบนโทรศัพท์มือถือที่คอยอัปโหลดรูปภาพจากเครื่องของคุณในเบื้องหลัง พร้อมฟีเจอร์ไทม์ไลน์, อัลบั้ม, การจดจำใบหน้า และการค้นหาด้วย machine-learning ที่สามารถค้นหาคำว่า "ชายหาด" หรือชื่อบุคคลได้โดยที่คุณไม่ต้องติดป้ายกำกับใดๆ คุณสามารถรันบริการนี้บน VPS ของคุณเอง ไฟล์ต้นฉบับจะถูกเก็บไว้ในดิสก์ของคุณ และไม่มีใครสามารถสแกนไฟล์เหล่านั้นเพื่อนำไปใช้ประโยชน์ทางการค้าได้ หากคุณยังลังเลระหว่างตัวเลือกนี้กับอีกตัวเลือกที่ได้รับความนิยม การเปรียบเทียบ PhotoPrism และ Immich ของเรา จะช่วยแสดงข้อมูลเปรียบเทียบทั้งในด้านการใช้ RAM ขั้นต่ำ, แอปพลิเคชันบนมือถือ และคำสั่งสำรองข้อมูลให้คุณเห็นภาพชัดเจน

การติดตั้งประกอบด้วยคอนเทนเนอร์ 4 รายการจากไฟล์ Docker Compose ของโปรเจกต์ ซึ่งใช้เวลาเพียง 10 นาที ส่วนที่เหลือของคู่มือนี้คือจุดที่มักพบปัญหา: คอนเทนเนอร์สำหรับ machine-learning ใช้หน่วยความจำสูงหากรันบนเครื่องขนาดเล็ก, ไฟล์ต้นฉบับใช้พื้นที่ดิสก์อย่างรวดเร็ว, แอปพลิเคชันบนมือถือต้องการ URL ของเซิร์ฟเวอร์ที่ถูกต้องแม่นยำ และคุณควรติดตั้ง HTTPS ไว้ด้านหน้าก่อนที่จะเปิดใช้งานผ่านเครือข่ายภายนอก นอกจากนี้ Immich ยังมีการอัปเดตที่อาจส่งผลกระทบต่อการใช้งาน (breaking changes) อยู่บ่อยครั้ง ดังนั้นการใช้ docker compose pull โดยไม่ระมัดระวังอาจทำให้เซิร์ฟเวอร์ของคุณไม่สามารถเริ่มทำงานได้ หากคุณให้ความสำคัญกับ 4 ประเด็นนี้ Immich จะเป็นระบบที่เสถียรมาก แต่หากละเลยไป คุณอาจต้องเสียเวลาแก้ไขปัญหาตลอดทั้งสุดสัปดาห์

ข้อกำหนดเบื้องต้นและข้อควรระวังที่สำคัญ

  • RAM: เอกสารอย่างเป็นทางการระบุขั้นต่ำไว้ที่ 6 GB และแนะนำที่ 8 GB โดยให้ถือว่า 4 GB รวมกับ swap เป็นขีดจำกัดต่ำสุดที่ยอมรับได้ คอนเทนเนอร์ immich-server และ Postgres ใช้ทรัพยากรไม่มากนัก แต่คอนเทนเนอร์ immich-machine-learning เป็นส่วนที่ใช้ทรัพยากรสูง เนื่องจากต้องโหลดโมเดล CLIP และโมเดลจดจำใบหน้าเข้าสู่ RAM เพื่อสร้างดัชนีการค้นหา หากรันบนเครื่องที่มี RAM 2 GB เคอร์เนลจะสั่งยุติการทำงานของโปรเซสนี้ทันที ควรเพิ่ม swap แม้ว่าคุณจะมี RAM 4 GB ก็ตาม
  • Disk: จัดสรรพื้นที่ให้ครอบคลุมคลังภาพทั้งหมดของคุณและเผื่อพื้นที่เพิ่ม ไฟล์ต้นฉบับของคุณจะถูกคัดลอกทั้งหมด นอกจากนี้ Immich ยังสร้างภาพขนาดย่อและภาพตัวอย่าง (ใช้พื้นที่เพิ่มประมาณ 10–20%) คลังภาพขนาด 200 GB ควรใช้พื้นที่จัดเก็บข้อมูลอย่างน้อย 300 GB ส่วน Postgres นั้นใช้พื้นที่น้อยกว่ามากเมื่อเทียบกัน
  • CPU: VPS แบบ KVM รุ่นใหม่ทั่วไปสามารถใช้งานได้ แต่การประมวลผล ML บน CPU จะทำงานช้า การสร้างดัชนีการค้นหาอัจฉริยะสำหรับการนำเข้าข้อมูลจำนวนมากอาจใช้เวลาทำงานเบื้องหลังนานหลายชั่วโมง ซึ่งเป็นเรื่องปกติและไม่จำเป็นต้องใช้ GPU
  • ชื่อโดเมน ที่ชี้ไปยัง VPS แอปบนมือถือต้องการ HTTPS endpoint เป็นอย่างมาก และคุณควรติดตั้ง reverse proxy ไว้ด้านหน้า การตั้งค่านี้มีรูปแบบเดียวกับ การทำ self-hosted Nextcloud ด้วย Docker, TLS และการสำรองข้อมูล โดย Immich เปรียบเสมือนคู่ขนานด้านรูปภาพของเซิร์ฟเวอร์ไฟล์ดังกล่าว
  • Docker และ Compose plugin ต้องติดตั้ง Docker Engine และ Compose v2 plugin จาก apt repository ของ Docker โดยตรง ตามที่ระบุไว้ใน คู่มือพื้นฐาน Docker Compose ของเรา

ขั้นตอนที่ 1: เพิ่ม swap ก่อนดำเนินการอื่นใด

สาเหตุที่พบบ่อยที่สุดที่ทำให้ Immich ล้มเหลวบน VPS ขนาดเล็กคือ container ของ ML ถูก OOM-killed ให้เตรียมพื้นที่ให้ kernel ทำงานได้ก่อน

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 จะหยุดทำงานระหว่างการทำ index บนเครื่องที่มี RAM 4 GB ได้อย่างมาก

ขั้นตอนที่ 2: ดาวน์โหลดไฟล์ compose และ env อย่างเป็นทางการมาใช้งานโดยตรง ห้ามคัดลอกเนื้อหา

Immich กำหนดเวอร์ชันของบริการและที่สำคัญที่สุดคืออิมเมจของฐานข้อมูลไว้ภายในไฟล์ที่แจกจ่ายมา อย่าคัดลอกไฟล์ compose จากบล็อก (รวมถึงบล็อกนี้) มาเป็นแหล่งข้อมูลหลัก ให้ดาวน์โหลด release assets โดยตรง:

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

ไฟล์เหล่านี้มาจาก release ที่มีการระบุแท็กไว้แล้ว ดังนั้นการอ้างอิงอิมเมจจึงตรงกัน ไฟล์ compose กำหนดบริการไว้ 4 รายการ ซึ่งควรทำความเข้าใจหน้าที่ของแต่ละบริการก่อนเริ่มแก้ไข:

  • immich-server (ghcr.io/immich-app/immich-server, คอนเทนเนอร์ immich_server) ทำหน้าที่เป็น API และเว็บ UI โดยฟังคำขอที่พอร์ต 2283 และทำการ mount ไฟล์ที่คุณอัปโหลดไว้ที่ /data
  • immich-machine-learning (ghcr.io/immich-app/immich-machine-learning, คอนเทนเนอร์ immich_machine_learning) ทำหน้าที่ค้นหาด้วย CLIP และจดจำใบหน้า โดยจะแคชโมเดลที่ดาวน์โหลดมาไว้ใน volume 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 สำหรับจัดการคิวงาน (job queues)

ขั้นตอนที่ 3: กำหนดค่า .env ซึ่งเป็นที่จัดเก็บรูปภาพและฐานข้อมูลของคุณ

เปิดไฟล์ .env และกำหนดค่า 4 รายการ ต่อไปนี้คือรายละเอียดที่คุณต้องตั้งค่า โดยให้คงเนื้อหาที่อยู่ใต้เส้นที่ระบุไว้ให้เหมือนเดิม

# 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

มีกฎ 2 ข้อที่จะช่วยให้คุณไม่ต้องปวดหัวในภายหลัง UPLOAD_LOCATION ควรชี้ไปยังดิสก์ลูกใหญ่ของคุณ หากคุณจะเชื่อมต่อ data volume ในภายหลัง ให้ตั้งค่านี้เป็น mount path ตั้งแต่เริ่มต้น เพราะการย้ายข้อมูลในภายหลังหมายถึงการต้องย้ายไฟล์ thumbnail และอัปเดต path ของ asset ทั้งหมด และ DB_DATA_LOCATION จะต้องอยู่บนดิสก์ภายในเครื่องเท่านั้น: การรัน Postgres บน NFS หรือ SMB share จะทำให้ข้อมูลเสียหาย ซึ่งเอกสารระบุเรื่องนี้ไว้อย่างชัดเจน หากคุณใช้เฉพาะตัวอักษรและตัวเลขใน DB_PASSWORD คุณจะหลีกเลี่ยงปัญหาบั๊กที่เกิดจากการ escape อักขระใน connection-string ได้

ขั้นตอนที่ 4: การรันครั้งแรกและการสร้างบัญชีผู้ดูแลระบบ

cd /opt/immich
sudo docker compose up -d
sudo docker compose ps

ผลลัพธ์ที่ถูกต้องคือคอนเทนเนอร์จำนวน 4 รายการ ซึ่งทั้งหมดต้องอยู่ในสถานะ 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 โดยเซิร์ฟเวอร์จะบันทึก log แจ้งว่ากำลังรอรับการเชื่อมต่อที่พอร์ต 2283 เมื่อพร้อมใช้งานแล้ว ให้เปิด http://YOUR_SERVER_IP:2283 ในเว็บเบราว์เซอร์ การเข้าใช้งานครั้งแรกจะแสดงวิซาร์ด Getting Started บัญชีแรกที่คุณสร้างขึ้นจะเป็นบัญชีผู้ดูแลระบบ โปรดตั้งรหัสผ่านที่คาดเดายาก บัญชีนี้จะมีสิทธิ์ในการจัดการการตั้งค่าเซิร์ฟเวอร์ การจัดการผู้ใช้ และการกำหนดค่า ML ที่คุณจำเป็นต้องใช้ในภายหลัง

ขั้นตอนที่ 5: แอปมือถือและการสำรองข้อมูลเบื้องหลัง

ติดตั้ง "Immich" จาก App Store หรือ Play Store บนหน้าจอเข้าสู่ระบบ แอปจะถามหา Server Endpoint URL ให้กรอก 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 หากคุณใช้งานคอนเทนเนอร์หลายตัวอยู่แล้ว Traefik พร้อม TLS อัตโนมัติสำหรับแอป Docker หลายตัว เป็นตัวเลือกที่จัดการได้สะอาดตาที่สุด โดยใช้เพียง label block เดียวในการกำหนดเส้นทาง photos.example.com ไปยังคอนเทนเนอร์ immich-server และดึง certificate มาให้คุณโดยอัตโนมัติ หากคุณต้องการใช้ nginx คู่มือ Let's Encrypt ด้วย Certbot และ nginx จะช่วยให้คุณได้รับ certificate และ block proxy_pass http://127.0.0.1:2283; เมื่อมี proxy แล้ว การเพิ่มบริการถัดไปส่วนใหญ่จะเป็นเพียงการเพิ่ม subdomain ใหม่ ซึ่งเป็นวิธีที่ทำให้หน้าเว็บสำหรับสื่ออย่าง Halcyon สกินร้านวิดีโอยุค 90 สำหรับ Jellyfin สามารถทำงานอยู่ข้างๆ Immich บนเครื่องเดียวกันได้ เช่นเดียวกับ HarnessRouter ที่โฮสต์เองเพื่อรวม Codex และ Claude Code ไว้หลัง API เดียว ซึ่งจะผูกไว้กับ loopback โดยตั้งใจและจะเข้าถึงได้ก็ต่อเมื่อ proxy ทำ TLS termination อยู่ด้านหน้าเท่านั้น ดังนั้นควรเปลี่ยนรหัสผ่านเริ่มต้นก่อนที่จะชี้ subdomain ไปยังบริการนั้น อย่างไรก็ตาม ไม่ใช่ทุกคอนเทนเนอร์ที่จำเป็นต้องมี public hostname ตัวอย่างเช่น เครื่องมือสำหรับผู้ดูแลระบบอย่าง เครื่องมือสแกนความปลอดภัย open-kritt ที่โฮสต์เอง ควรแยกออกจาก proxy โดยสิ้นเชิงและเข้าถึงผ่าน SSH tunnel ในกรณีที่คุณต้องการเปิดใช้งาน UI เท่านั้น บริการอื่นๆ อาจข้ามการใช้ proxy ไปเลยหากไม่ได้สื่อสารผ่านโปรโตคอล HTTP ซึ่ง เซิร์ฟเวอร์ relay ของ RustDesk ที่โฮสต์เอง เป็นตัวอย่างที่ชัดเจนที่สุด โดยบริการนี้จะฟังพอร์ต TCP และ UDP ดิบหลายพอร์ตและต้องการกฎ firewall มากกว่าการใช้ subdomain มีการตั้งค่า proxy หนึ่งรายการที่สำคัญสำหรับ Immich คือการเพิ่มขีดจำกัดขนาดไฟล์อัปโหลด เนื่องจากวิดีโอจากโทรศัพท์มีขนาดใหญ่ ใน nginx ให้ตั้งค่า client_max_body_size 50000M; ภายใน server block เนื่องจากค่าเริ่มต้นที่ 1 MB จะปฏิเสธการอัปโหลดวิดีโอด้วยข้อผิดพลาด 413 Request Entity Too Large หาก proxy ของคุณทำหน้าที่ตอบสนองการตรวจสอบ Let's Encrypt HTTP-01 challenges ด้วย ต้องตรวจสอบให้แน่ใจว่า /.well-known/immich ยังคงถูกส่งไปยัง Immich ไม่ใช่ส่งไปยังตัวจัดการ challenge

กฎที่แอปบังคับใช้คือ endpoint ต้องสามารถเข้าถึงได้ผ่าน URL ที่คุณระบุไว้อย่างถูกต้อง แอปจะยอมรับ http://YOUR_SERVER_IP:2283 แบบธรรมดา (คำแนะนำการเข้าสู่ระบบของแอปคือ http://your-server-ip:port) แต่การเชื่อมต่อใดๆ ที่ผ่านอินเทอร์เน็ตควรเป็น HTTPS การใช้ scheme ที่ไม่ถูกต้อง หรือการใช้ IP โดยตรงโดยไม่ระบุพอร์ต คือสาเหตุที่ทำให้เกิดข้อความ "แอปไม่สามารถเข้าถึงเซิร์ฟเวอร์ได้" ซึ่งจะอธิบายถึงความล้มเหลวที่ระบุไว้ด้านล่างนี้

ขั้นตอนที่ 7: ไลบรารีภายนอกเทียบกับการอัปโหลด และการนำเข้าโครงสร้างรูปภาพที่มีอยู่เดิม

วิธีการนำรูปภาพเข้าสู่ Immich มี 2 รูปแบบ ซึ่งมีความแตกต่างกันดังนี้:

  • การอัปโหลด (Uploads) คือสินทรัพย์ที่ Immich เป็นเจ้าของ แอปพลิเคชันหรือตัวอัปโหลดบนเว็บจะคัดลอกไฟล์เข้าไปยัง UPLOAD_LOCATION โดย Immich สามารถเปลี่ยนชื่อ ย้าย และลบไฟล์เหล่านี้ได้
  • ไลบรารีภายนอก (External libraries) คือการนำเข้าไฟล์แบบอ่านได้อย่างเดียว (read-only) ซึ่งไฟล์เหล่านั้นถูกจัดเก็บอยู่ในโฟลเดอร์บนเซิร์ฟเวอร์ของคุณอยู่แล้ว เช่น โครงสร้าง Pictures แบบเก่า หรือการแชร์ไฟล์จาก NAS โดย Immich จะทำดัชนีไฟล์เหล่านั้นในตำแหน่งเดิมและแสดงผลในไทม์ไลน์ แต่จะไม่แก้ไขหรือลบไฟล์ต้นฉบับโดยเด็ดขาด

ในการนำเข้าโครงสร้างไฟล์ที่มีอยู่เดิม ให้ทำการ 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 จะไม่สามารถแก้ไขไฟล์ต้นฉบับได้ ให้สร้างคอนเทนเนอร์ขึ้นใหม่ด้วยคำสั่ง sudo docker compose up -d จากนั้นในหน้าเว็บ UI ให้ไปที่รูปโปรไฟล์ของคุณ → Administration → External Libraries → Create Library เลือกผู้ใช้ที่เป็นเจ้าของ คลิก Add ภายใต้หัวข้อ Folders แล้วระบุ path ภายใน คอนเทนเนอร์ คือ /mnt/media/photos ไม่ใช่ path บนโฮสต์คือ /srv/photos จากนั้นคลิก Scan การใช้ path บนโฮสต์แทน path ภายในคอนเทนเนอร์เป็นข้อผิดพลาดที่พบบ่อยที่สุดในการตั้งค่าไลบรารีภายนอก ซึ่งจะส่งผลให้การสแกนไม่พบไฟล์ใดๆ และรายงานจำนวนสินทรัพย์เป็นศูนย์

ขั้นตอนที่ 8: วินัยในการอัปเกรดที่ Immich ต้องการ

นี่คือส่วนที่แยกความแตกต่างระหว่าง Immich ที่ทำงานได้ดีกับ Immich ที่พัง Immich มีรอบการปล่อยซอฟต์แวร์ที่รวดเร็วและไม่มีการ backport การแก้ไขหรือรองรับการ downgrade แท็ก v3 แบบลอยตัวเป็นวิธีที่รองรับอย่างเป็นทางการในการติดตามรุ่นต่างๆ และ Immich พยายามจำกัดการเปลี่ยนแปลงที่ส่งผลกระทบต่อระบบ (breaking changes) ไว้ที่รุ่นหลักเท่านั้น อย่างไรก็ตาม ระบบจะอัปเกรดให้คุณทันทีที่คุณ pull ไม่ว่าคุณจะได้อ่านบันทึกการเปลี่ยนแปลงหรือไม่ก็ตาม และการอัปเกรดที่คุณไม่ได้วางแผนไว้จะไม่สามารถย้อนกลับได้ นิสัยการระบุเวอร์ชัน (pin) แล้วอ่านบันทึกการเปลี่ยนแปลงก่อนเป็นสิ่งที่ควรนำไปใช้กับ container ทุกตัวที่ทำงานต่อเนื่องบนเซิร์ฟเวอร์ ซึ่งเป็นเหตุผลว่าทำไม ตัวแทน KiroCrew ที่โฮสต์เองจึงถูกระบุเวอร์ชันไว้ที่แท็กที่ใช้งานได้ดี แทนที่จะปล่อยให้เปลี่ยนเวอร์ชันเองเมื่อมีการรีสตาร์ท วินัยที่ต้องปฏิบัติมีดังนี้:

  1. ระบุเวอร์ชันให้ชัดเจน (Pin a version): ตั้งค่า 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. อัปเดตแอปบนมือถือก่อน เซิร์ฟเวอร์จะสื่อสารได้เฉพาะกับเวอร์ชันหลักที่ตรงกันเท่านั้น และโดยทั่วไปแอปจะรองรับเวอร์ชันหลักปัจจุบันและเวอร์ชันก่อนหน้า เมื่อเซิร์ฟเวอร์ใหม่กว่าแอป รุ่นปัจจุบัน (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: การสำรองข้อมูล, การดัมพ์ฐานข้อมูลรวมถึงไฟล์ต้นฉบับ และการทดสอบ

การสำรองข้อมูล Immich ประกอบด้วยสองส่วน และหากขาดส่วนใดส่วนหนึ่งไปจะใช้งานไม่ได้ ฐานข้อมูล (database) จะเก็บโครงสร้างอัลบั้ม, ใบหน้า, ดัชนีการค้นหา และแผนผังความสัมพันธ์ระหว่างไฟล์กับข้อมูล ส่วน ไดเรกทอรีต้นฉบับ (originals directory) จะเก็บไฟล์รูปภาพจริง หากกู้คืนเพียงส่วนใดส่วนหนึ่ง คุณจะได้เพียงรูปภาพที่ไม่มีการจัดระเบียบ หรือได้เพียงโครงสร้างเปล่าที่ชี้ไปยังไฟล์ที่หายไป รูปแบบสองส่วนนี้ไม่ใช่เรื่องแปลกสำหรับ Immich: ระบบสนับสนุน Chatwoot ที่โฮสต์เอง ก็ต้องการการจับคู่ระหว่างการดัมพ์ Postgres กับไดเรกทอรี uploads เช่นกัน มิฉะนั้นกล่องข้อความที่กู้คืนมาจะไม่มีไฟล์แนบ การคัดลอกไดเรกทอรีข้อมูล Postgres ทั้งกิ่งดูเหมือนจะเป็นทางลัดแทนการดัมพ์ข้อมูล แต่ไม่ใช่การสำรองข้อมูลที่ใช้งานได้จริง ซึ่งเป็นกับดักที่ คู่มือการสำรองและกู้คืน 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 entry หรือ systemd timer ระบบจำเป็นต้องมีช่องทางแจ้งเตือนเมื่อการสำรองข้อมูลล้มเหลว การใช้ systemd OnFailure= unit ที่เชื่อมต่อกับ เซิร์ฟเวอร์ ntfy ของคุณเอง จะช่วยส่งข้อความแจ้งเตือนไปยังโทรศัพท์ของคุณในคืนที่การดัมพ์ข้อมูลเกิดปัญหา แทนที่จะปล่อยให้คุณมารู้ตัวในตอนที่ต้องกู้คืนข้อมูล ให้เริ่มจากการสำรองฐานข้อมูลก่อนแล้วจึงสำรองไฟล์ เพื่อให้การดัมพ์ข้อมูลไม่อ้างอิงถึงรูปภาพที่ยังไม่ได้คัดลอก สำหรับ external libraries ให้สำรองข้อมูลแยกต่างหากจากแหล่งที่มาจริง เนื่องจาก Immich ไม่ได้เป็นเจ้าของไฟล์เหล่านั้น

ตอนนี้มาถึงส่วนที่ทุกคนมักข้ามไป: การทดสอบการกู้คืน การกู้คืนต้องทำบน stack ที่ สะอาด ซึ่งเซิร์ฟเวอร์ยังไม่เคยเริ่มทำงาน และบนอิมเมจ Postgres ที่มี vector extension เข้ากันได้กับไฟล์ดัมพ์ ซึ่งเป็นเหตุผลว่าทำไมคุณจึงไม่ควรเปลี่ยน tag ของอิมเมจฐานข้อมูลโดยพลการ บนเครื่องทดสอบที่ใช้ 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

การเขียนทับ sed ของ search_path เป็นสิ่งที่จำเป็นสำหรับฐานข้อมูล VectorChord หากข้ามขั้นตอนนี้ไป การกู้คืนจะหยุดชะงักกลางคัน เมื่อ stack เริ่มทำงานใหม่พร้อมกับไฟล์ต้นฉบับของคุณ ให้เปิด web UI หากรูปภาพและอัลบั้มของคุณปรากฏขึ้น แสดงว่าการสำรองข้อมูลของคุณใช้งานได้จริง หากคุณไม่เคยทดสอบขั้นตอนนี้ คุณไม่ได้มีระบบสำรองข้อมูล คุณมีเพียงความหวังเท่านั้น

รูปแบบความล้มเหลวและข้อความที่พบ

คอนเทนเนอร์ ML ถูก OOM-killed sudo docker compose logs immich-machine-learning สิ้นสุดลงกะทันหัน docker compose ps แสดงสถานะ Restarting และ exit code คือ 137 คำสั่ง sudo dmesg | grep -i oom ยืนยันสาเหตุด้วย Out of memory: Killed process ... (python3) จากนั้นงานค้นหาและงานวิเคราะห์ใบหน้าจะค้าง สาเหตุเกิดจาก RAM ไม่เพียงพอสำหรับโมเดล วิธีแก้ไขตามลำดับคือ: เพิ่ม swap (ขั้นตอนที่ 1), เพิ่ม RAM ให้ VPS หรือหากไม่สามารถทำได้จริง ให้ไปที่ Administration → Settings → Machine Learning Settings แล้วปิดสวิตช์ Machine Learning หลัก ซึ่งจะเป็นการปิดฟีเจอร์ ML ทั้งหมดพร้อมกัน การปิดเฉพาะ Smart Search และ Facial Recognition นั้นไม่เพียงพอ เพราะ OCR และโมเดลประเภทอื่นจะยังคงเปิดใช้งานอยู่โดยค่าเริ่มต้น คุณจะยังคงสำรองข้อมูลและอัลบั้มได้ แต่จะสูญเสียความสามารถในการค้นหาตามเนื้อหา การลบเซอร์วิส immich-machine-learning ออกจากไฟล์ compose จะให้ผลลัพธ์เช่นเดียวกัน

เซิร์ฟเวอร์ Immich ไม่ยอมเริ่มทำงานหลังการอัปเกรด คอนเทนเนอร์ Postgres อาจทำงานได้ตามปกติ แต่เป็น immich_server ที่ตรวจสอบเวอร์ชันของ vector extension ในขณะเริ่มทำงานแล้วปฏิเสธที่จะรันต่อ โดย log จะวนลูปด้วยข้อความเช่น 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. หรือใน stack รุ่นเก่าจะเป็น The pgvecto.rs extension is not available in this Postgres instance. สาเหตุเกิดจากอิมเมจฐานข้อมูลมีเวอร์ชันของ extension เก่ากว่าเวอร์ชันที่ข้อมูลของคุณถูกอัปเกรดไปแล้ว ซึ่งมักเกิดจากการแก้ไข image tag ด้วยตนเอง หรือการกู้คืนข้อมูลจาก dump รุ่นใหม่ลงบนอิมเมจรุ่นเก่า วิธีแก้ไขคือใช้อิมเมจ Postgres ที่ตรงกัน ใช้ไฟล์ compose จากรุ่นที่ตรงกับฐานข้อมูลของคุณ ห้ามทำการ downgrade และกู้คืนข้อมูลลงบนอิมเมจที่เข้ากันได้เท่านั้น

แอปมือถือไม่สามารถเชื่อมต่อเซิร์ฟเวอร์ได้ หน้าจอเข้าสู่ระบบแสดงข้อผิดพลาดการเชื่อมต่อ เช่น Could not connect to server หลังจากที่คุณกรอก URL สาเหตุที่พบบ่อยคือ: คุณพิมพ์ http:// ในขณะที่พร็อกซีให้บริการเฉพาะ https://, คุณเชื่อมต่อตรงไปยัง backend แต่ไม่ได้ระบุพอร์ต ทำให้ระบบพยายามเชื่อมต่อที่ example.com (พอร์ต 443) แทนที่จะเป็น example.com:2283, reverse proxy ไม่ได้ส่งต่อ /api หรือพร็อกซีที่จัดการ Let's Encrypt HTTP-01 challenges กำลังส่งเส้นทาง /.well-known/immich ไปยังที่อื่นที่ไม่ใช่ Immich วิธีแก้ไขคือกรอก URL แบบเต็ม https://photos.example.com และตรวจสอบให้แน่ใจว่าสามารถโหลดผ่านเบราว์เซอร์บนมือถือได้ก่อน หากเบราว์เซอร์ใช้งานได้แต่แอปใช้งานไม่ได้ แสดงว่าพร็อกซีอาจตัด path ออกหรือส่งเส้นทาง /.well-known/immich ผิดพลาด หรือใบรับรองเป็นแบบ self-signed ซึ่งแอปจะปฏิเสธด้วยข้อผิดพลาด handshake เว้นแต่คุณจะเปิดใช้งานการรองรับ self-signed certificate ในการตั้งค่าของแอป

พื้นที่ดิสก์เต็มระหว่างการนำเข้าข้อมูล การอัปโหลดเริ่มล้มเหลว รูปย่อ (thumbnails) กลายเป็นสีว่างเปล่า และ log แสดง ENOSPC: no space left on device หรือจาก Postgres แสดง could not extend file ... No space left on device คำสั่ง df -h แสดงว่าโวลุ่ม UPLOAD_LOCATION เต็ม 100% นี่คือเหตุผลที่คุณต้องประเมินขนาดดิสก์ก่อนนำเข้าคลังข้อมูลขนาดใหญ่ การกู้คืนทำได้โดยการเพิ่มโวลุ่มที่มีขนาดใหญ่ขึ้น หยุดการทำงานของ stack ย้าย UPLOAD_LOCATION ไปยังโวลุ่มใหม่ อัปเดต .env แล้วเริ่มระบบใหม่ หรือขยายขนาดดิสก์เดิมหากผู้ให้บริการของคุณรองรับ Postgres อาจค้างได้หากพื้นที่เต็ม ดังนั้นให้เคลียร์พื้นที่และรีสตาร์ทคอนเทนเนอร์ฐานข้อมูลก่อนที่จะสรุปว่าข้อมูลเสียหาย

FAQ

Immich ต้องการ RAM และพื้นที่ดิสก์เท่าใด?

ข้อกำหนดอย่างเป็นทางการของ Immich คือ RAM ขั้นต่ำ 6 GB และแนะนำที่ 8 GB โดย 4 GB พร้อม swap คือขีดจำกัดขั้นต่ำที่ใช้งานได้จริงสำหรับคลังภาพขนาดเล็ก อย่างไรก็ตามควรตั้งค่า swap ไว้เสมอเนื่องจากคอนเทนเนอร์ machine-learning เป็นส่วนที่ใช้ทรัพยากรสูง สำหรับพื้นที่ดิสก์ ให้เตรียมพื้นที่เท่ากับขนาดคลังภาพทั้งหมดของคุณบวกเพิ่มอีกประมาณ 10–20% สำหรับ thumbnail และ preview ที่ถูกสร้างขึ้น โดยต้องเก็บไว้บน local storage เท่านั้น ห้ามวางไดเรกทอรีข้อมูลของ Postgres ไว้บน network share หากคุณยังตัดสินใจไม่ได้ว่าจะรันบริการอะไรเพิ่มเติม คู่มือสิ่งที่ควร self-host ในปี 2026 ได้เปรียบเทียบการใช้ทรัพยากรของ Immich ไว้กับบริการอื่นๆ

ฉันสามารถรัน Immich โดยไม่มี GPU ได้หรือไม่?

ได้ คอนเทนเนอร์ machine-learning สามารถทำงานบน CPU ได้ตามปกติ GPU จะช่วยเพิ่มความเร็วในการทำ smart-search indexing และการแปลงรหัสวิดีโอ (หากใช้ image variant ที่เหมาะสม) เท่านั้น บน CPU การทำ index เริ่มต้นของคลังภาพขนาดใหญ่อาจใช้เวลาหลายชั่วโมงในเบื้องหลัง แต่จะไม่ขัดขวางการสำรองข้อมูลหรือการเรียกดูภาพ หากเครื่องของคุณมีสเปกต่ำเกินกว่าจะรัน ML ได้ คุณสามารถปิดการใช้งาน machine learning ทั้งหมดได้ด้วยสวิตช์ในหน้าการตั้งค่าผู้ดูแลระบบและยังคงใช้งานฟังก์ชันอื่นได้ตามปกติ

ฉันจะอัปเกรด Immich อย่างปลอดภัยได้อย่างไร?

ให้ล็อกเวอร์ชันของ IMMICH_VERSION ไว้ที่ tag เฉพาะเจาะจง เช่น v3.0.2 อ่าน release notes ก่อนการอัปเกรดทุกครั้ง และสำรองข้อมูลฐานข้อมูลก่อนเสมอ เนื่องจากอิมเมจ Postgres ถูกระบุเวอร์ชันไว้ภายใน docker-compose.yml แทนที่จะใช้ IMMICH_VERSION คุณจึงต้องดาวน์โหลดไฟล์ compose และ example.env ใหม่จากเวอร์ชันที่คุณต้องการ แล้วนำค่าคอนฟิกของคุณไปใส่ใหม่ จากนั้นจึงรัน docker compose pull && docker compose up -d ห้ามปล่อยให้เวอร์ชันอัปเดตโดยอัตโนมัติโดยไม่ตรวจสอบ เพราะ Immich ไม่รองรับการ downgrade ดังนั้นการอัปเกรดที่คุณไม่ได้ศึกษาข้อมูลมาก่อนจะไม่สามารถย้อนกลับได้

ฉันต้องสำรองข้อมูลอะไรบ้าง?

สองส่วนควบคู่กัน: pg_dump ของฐานข้อมูล immich และไดเรกทอรี UPLOAD_LOCATION ที่เก็บไฟล์ต้นฉบับทั้งหมด ฐานข้อมูลจะเก็บข้อมูลอัลบั้ม ใบหน้า และการจับคู่ระหว่าง asset กับไฟล์ ส่วนไดเรกทอรีจะเก็บรูปภาพจริง การกู้คืนข้อมูลจำเป็นต้องใช้ทั้งสองส่วนรวมถึงอิมเมจฐานข้อมูลที่มี vector extension ที่เข้ากันได้ ให้ทำการ dump ฐานข้อมูลก่อนแล้วจึงคัดลอกไฟล์ และควรทดสอบการกู้คืนบนเครื่องทดสอบอย่างน้อยหนึ่งครั้ง การสำรองข้อมูลที่ไม่ได้ผ่านการทดสอบถือว่าไม่ใช่การสำรองข้อมูล

ฉันจะนำเข้าโฟลเดอร์รูปภาพที่มีอยู่เดิมได้อย่างไร?

ให้ mount โฟลเดอร์ดังกล่าวแบบอ่านอย่างเดียว (read-only) เข้าไปในคอนเทนเนอร์ immich-server ในฐานะ volume เพิ่มเติม (ตัวอย่างเช่น - /srv/photos:/mnt/media/photos:ro) จากนั้นสร้างคอนเทนเนอร์ใหม่ แล้วไปที่ Administration → External Libraries เพื่อสร้าง library และเพิ่ม path ของ container คือ /mnt/media/photos Immich จะทำ index ไฟล์จากตำแหน่งนั้นโดยตรงและจะไม่แก้ไขหรือลบไฟล์ของคุณ ข้อผิดพลาดที่พบบ่อยที่สุดคือการใส่ path ของ host แทนที่จะเป็น path ของ container ซึ่งจะทำให้การสแกนไม่พบไฟล์ใดๆ