SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-08-13

Cara Backup dan Restore Immich di VPS

Pelajari isi backup Immich, alasan menyalin direktori data Postgres bukan backup, serta kesalahan restore yang membuat timeline kosong meski disk penuh.

Isi yang harus ada dalam backup Immich

Backup Immich terdiri dari tiga hal yang diambil pada waktu yang sama. File asli di UPLOAD_LOCATION. SQL dump database Postgres. File .env dan docker-compose.yml yang menjelaskan stack. Pemulihan berarti memasukkan kembali dump tersebut ke database baru saat server Immich dihentikan, lalu hanya menjalankan stack lainnya setelah proses itu selesai. Jika urutannya salah, Immich dapat berjalan tetapi menampilkan timeline kosong di atas disk yang penuh.

Pemisahan ini penting karena Immich menyimpan statusnya di dua tempat yang tidak saling mengetahui. Postgres menyimpan setiap album, setiap cluster wajah, setiap shared link, setiap akun pengguna dan API key, serta path tersimpan untuk setiap aset. Filesystem menyimpan data piksel. Jika file dipulihkan tanpa database, Immich tidak menampilkan apa pun. Jika database dipulihkan tanpa file, setiap aset akan terbuka sebagai gambar rusak.

Perintah di sini ditulis untuk Immich v3.1.0, yaitu rilis yang berlaku pada awal Agustus 2026. Proyek ini merilis pembaruan dengan cepat dan prosedur backup yang didokumentasikan telah berubah beberapa kali. Karena itu, periksa versi yang benar-benar Anda jalankan sebelum menyalin apa pun. Jika stack belum berjalan, mulai dengan panduan instalasi Immich lalu kembali ke sini.

Pahami tujuan setiap path

Dua variabel dalam .env menentukan seluruh konfigurasi pada halaman ini. UPLOAD_LOCATION adalah direktori induk tempat Immich menyimpan semua media. DB_DATA_LOCATION adalah direktori data Postgres.

example.env bawaan menetapkan UPLOAD_LOCATION=./library. Nilai default ini membingungkan karena Immich kemudian membuat folder bernama library di dalam direktori tersebut. File asli Anda akhirnya berada di ./library/library. Tetapkan path absolut agar skrip pencadangan tidak pernah bergantung pada direktori tempat Anda menjalankannya.

UPLOAD_LOCATION=/srv/immich/data
DB_DATA_LOCATION=/srv/immich/postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
IMMICH_VERSION=v3.1.0

Di dalam UPLOAD_LOCATION, Immich membuat beberapa folder. Tiga di antaranya berisi data yang tidak dapat dibuat ulang oleh tugas apa pun:

  • library: file asli yang disusun berdasarkan template penyimpanan Anda
  • upload: file asli yang belum dipindahkan ke tata letak berdasarkan template, serta unggahan yang masih diproses
  • profile: foto profil pengguna

Jika library hilang, foto tersebut juga hilang. Immich tidak menyimpan salinan kedua file asli di tempat lain.

Mengapa menyalin direktori data Postgres bukan backup

DB_DATA_LOCATION tampak seperti target yang mudah. Direktori dapat disalin dengan rsync, dan proses penyalinan selesai tanpa error. Namun, hasilnya tetap bukan backup karena dua alasan yang dapat menyebabkan kegagalan.

Alasan pertama adalah ketidakkonsistenan data. Postgres terlebih dahulu menulis setiap perubahan ke write-ahead log (WAL), lalu menerapkannya ke file tabel pada checkpoint. Jadi, pada setiap saat, file di disk dapat berada di tengah proses perubahan. Penyalinan bertahap yang berlangsung selama empat menit dapat membaca file pertama pada 02:00 dan file terakhir pada 02:04. Kedua file tersebut tidak berasal dari transaksi yang sama. Saat Postgres dijalankan menggunakan hasil penyalinan itu, Postgres dapat menolak start dengan PANIC: could not locate a valid checkpoint record, atau start lalu berhenti saat pertama kali membaca page yang rusak dengan invalid page in block 1234 of relation base/16384/.... Hasil penyalinan tersebut tidak dapat dipulihkan.

Alasan kedua tetap berlaku meskipun Anda menghentikan semua proses terlebih dahulu. Direktori data Postgres terikat pada binary yang menulisnya. Immich mengunci image database berdasarkan digest, saat ini ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0. Image tersebut adalah Postgres 14 dengan dua ekstensi pencarian vektor yang telah dikompilasi. Direktori data yang ditulis oleh build tersebut tidak dapat dibuka oleh Postgres major version lain. Direktori tersebut juga tidak dapat dibuka oleh build dengan versi ekstensi yang berbeda. Host pemulihan harus mereproduksi image tersebut secara persis. SQL dump tidak memiliki ketergantungan ini. Isinya berupa teks, dan server kompatibel mana pun dapat memutarnya kembali.

pg_dump secara langsung mengatasi masalah ketidakkonsistenan data. Perintah tersebut membaca seluruh database dalam satu snapshot MVCC (multi-version concurrency control). Dengan demikian, data yang dibaca mencerminkan kondisi database pada satu waktu, sementara penulisan lain tetap berlangsung. Karena itu, Anda tidak perlu menghentikan Postgres untuk membuat dump.

Bagian yang dapat dikecualikan dari backup

Bagian berikut dibuat ulang secara otomatis, sehingga dapat dilewati:

  • thumbs: gambar pratinjau dan thumbnail
  • encoded-video: video yang telah ditranskode
  • DB_DATA_LOCATION: dibuat ulang dari dump
  • volume Docker model-cache: model machine learning, yang akan diunduh kembali saat diperlukan

Melewati bagian tersebut merupakan kompromi, bukan keuntungan tanpa biaya. Membangun ulang thumbnail dan video transkode untuk library besar dapat menghabiskan waktu CPU berjam-jam pada VPS kecil, dan timeline akan menampilkan placeholder abu-abu selama proses berlangsung. Jalankan kembali proses tersebut dari Administration > Jobs, dengan "Generate Thumbnails" dan "Transcode Videos" diatur untuk berjalan pada aset yang belum tersedia. Jika target backup Anda masih memiliki ruang, sertakan bagian tersebut agar tidak perlu menunggu. Jika Anda hampir mencapai batas penyimpanan, kecualikan bagian tersebut dan rencanakan proses pembangunan ulang. Mengukur ukuran library Immich menjelaskan seberapa besar pertumbuhan folder tersebut dibandingkan dengan file asli.

Ada satu folder lain yang perlu diketahui. UPLOAD_LOCATION/backups menyimpan dump database otomatis milik Immich, yang dibuat setiap hari pada 02:00 dan menyimpan 14 dump terakhir. Pengaturannya tersedia di Administration > Settings > Backup. Dump tersebut tidak membebani Anda dan benar-benar berguna. Namun, dump tersebut berada pada disk yang sama dengan library yang dilindunginya, sehingga berguna untuk menangani migrasi yang bermasalah, bukan server yang mati total. Tetap buat dump Anda sendiri, karena dump yang Anda picu sendiri dibuat pada waktu yang sama dengan snapshot file yang terkait dengannya.

Ambil dump database

docker exec -t immich_postgres pg_dump --clean --if-exists \
  --dbname=immich --username=postgres \
  | gzip > /srv/immich/backup/immich.sql.gz

Ganti immich dan postgres dengan DB_DATABASE_NAME dan DB_USERNAME jika Anda mengubahnya. --clean --if-exists menambahkan DROP ... IF EXISTS di depan setiap CREATE, sehingga dump dapat diputar ulang ke database yang sudah berisi objek, bukan berhenti pada objek pertama.

Sekarang perhatikan detail yang sering merusak skrip pencadangan tanpa terlihat. Perintah tersebut adalah pipeline, dan shell melaporkan status keluar dari perintah terakhir dalam pipeline. Jika pg_dump gagal karena kata sandi salah atau container tidak berjalan, gzip menerima aliran kosong, menulis file gzip yang valid, lalu keluar dengan status 0. Skrip Anda mencatat keberhasilan, tetapi file cadangan yang dihasilkan hanya berukuran 20 byte. Letakkan pipefail di bagian awal setiap skrip pencadangan:

#!/usr/bin/env bash
set -euo pipefail

Kemudian periksa hasilnya, bukan sekadar mempercayai kode keluar:

ls -lh /srv/immich/backup/immich.sql.gz
gunzip -c /srv/immich/backup/immich.sql.gz | head -n 3

Baris pertama dump yang sehat berbunyi -- PostgreSQL database dump. File berukuran beberapa ratus byte berarti dump gagal, apa pun yang dilaporkan skrip.

Catat build yang menulisnya di samping dump:

docker inspect --format '{{.Config.Image}}' immich_server > /srv/immich/backup/immich-version.txt

Jangan mengandalkan .env untuk hal ini. File bawaan menetapkan IMMICH_VERSION=v3, yaitu tag mengambang yang mengikuti setiap rilis 3.x, sehingga tag tersebut tidak memberi tahu build mana yang sebenarnya menulis dump. Tetapkan tag yang tepat dalam .env juga.

Jedaikan server, lalu buat snapshot dengan restic

File di bawah UPLOAD_LOCATION tidak bersifat immutable selama Immich berjalan. Server menulis upload baru, dan tugas template penyimpanan memindahkan file antar-direktori. Jika alat backup membaca file saat penulisan belum selesai, alat tersebut menyimpan byte yang sudah terbaca seolah-olah itu seluruh file, tanpa melaporkan error. Hentikan container server selama proses berlangsung:

docker stop immich_server

Biarkan immich_postgres tetap berjalan karena dump memerlukannya. Antarmuka web dan aplikasi mobile akan offline sampai server dijalankan kembali. Pada instance rumah tangga yang berjalan pukul 03:00, kondisi ini biasanya tidak menjadi masalah.

restic sesuai untuk kebutuhan ini karena melakukan deduplikasi dan enkripsi sebelum data meninggalkan server. Arahkan restic ke repository yang tidak berada di server ini:

export RESTIC_REPOSITORY=sftp:backup@backup.example.com:/srv/restic/immich
export RESTIC_PASSWORD_FILE=/root/.restic-password
restic init

Object storage bekerja dengan cara yang sama dan merupakan pilihan yang lebih baik jika Anda ingin salinan berada sepenuhnya di luar perangkat keras milik sendiri:

export RESTIC_REPOSITORY=s3:https://s3.example.com/immich-backup
export AWS_ACCESS_KEY_ID=your-access-key
export AWS_SECRET_ACCESS_KEY=your-secret-key
restic init

Endpoint tersebut dapat berupa bucket MinIO yang Anda jalankan sendiri pada mesin kedua atau provider yang kompatibel dengan S3. Repository pada disk yang sama dengan library hanya melindungi Anda dari penghapusan yang keliru, bukan dari risiko lainnya.

Selanjutnya, buat snapshot yang mencantumkan semua hal penting:

restic backup \
  /srv/immich/backup/immich.sql.gz \
  /srv/immich/backup/immich-version.txt \
  /srv/immich/data/library \
  /srv/immich/data/upload \
  /srv/immich/data/profile \
  /srv/immich/.env \
  /srv/immich/docker-compose.yml
docker start immich_server

restic membaca seluruh tree pada setiap proses, tetapi hanya mengunggah blok yang belum pernah dilihat sebelumnya. Karena itu, snapshot pertama memindahkan seluruh library Anda, sedangkan setiap snapshot berikutnya hanya memindahkan foto baru pada hari tersebut.

Retensi dan kunci yang harus disimpan di tempat lain

restic forget --prune --keep-daily 7 --keep-weekly 5 --keep-monthly 12

forget menghapus snapshot dari indeks. --prune adalah bagian yang menghapus data yang sebelumnya hanya dirujuk oleh snapshot tersebut. Jalankan forget tanpa --prune, dan biaya penyimpanan Anda tidak akan pernah turun.

Pemeriksaan struktur tidak mahal, jadi jalankan sekali setiap minggu:

restic check

Pemeriksaan ini memastikan metadata repository konsisten. Pemeriksaan ini tidak membaca data Anda. Sekali sebulan, baca ulang sampel data dan periksa kecocokannya dengan hash yang tercatat:

restic check --read-data-subset=5%

Ini adalah satu-satunya pemeriksaan yang dapat mendeteksi kerusakan senyap pada backend penyimpanan, karena pemeriksaan ini mengunduh blok nyata dan menghitung ulang checksum-nya. --read-data penuh pada pustaka foto berarti mengunduh seluruh repository. Pada object storage dengan biaya berdasarkan penggunaan, hal ini memerlukan biaya nyata. Karena itu, subset bergilir adalah cara yang benar-benar digunakan.

Sekarang bagian yang sering dilewatkan. Password repository restic tidak dapat dipulihkan. Tidak ada reset dan tidak ada tiket dukungan. Jika satu-satunya salinan berada di /root/.restic-password pada server yang sedang Anda coba pulihkan, backup Anda hanya menjadi data terenkripsi yang tidak berguna. Hal yang sama berlaku untuk access key object storage dan DB_PASSWORD dari .env. Simpan semuanya di tempat yang tidak bergantung pada mesin ini tetap aktif: cetak dan simpan di laci, atau gunakan password manager yang berjalan pada hardware berbeda. Jika password manager tersebut juga di-host sendiri, perlakuannya harus sama, dan mencadangkan Vaultwarden merupakan tugas tersendiri.

Pulihkan Immich dengan urutan yang benar

Urutan pemulihan menentukan apakah backup yang baik dapat mengembalikan timeline atau justru menghasilkan timeline kosong. Ikuti urutan ini pada host baru.

Kembalikan konfigurasi terlebih dahulu. Konfigurasi menentukan versi yang harus dijalankan dan lokasi path.

restic restore latest --target /restore \
  --include /srv/immich/.env \
  --include /srv/immich/docker-compose.yml \
  --include /srv/immich/backup

Tetapkan versinya sebelum menjalankan apa pun. Baca immich-version.txt, tetapkan IMMICH_VERSION di .env ke tag yang sama persis, dan jangan gunakan release terbaru untuk saat ini. Immich tidak mendukung downgrade, bahkan antarpatch release. Jika server yang lebih baru dijalankan terhadap dump yang lebih lama lalu menjalankan migration, tidak ada cara untuk mengembalikannya.

Pulihkan media.

restic restore latest --target /restore --include /srv/immich/data

Kemudian pindahkan library, upload, dan profile agar berada tepat di dalam direktori yang ditunjuk oleh UPLOAD_LOCATION pada host ini. Path pada host dapat berubah karena compose file mengikat direktori tersebut ke path tetap di dalam container. Struktur di dalamnya tidak boleh berubah.

Jalankan database secara terpisah. Biarkan DB_DATA_LOCATION kosong agar Postgres menginisialisasi cluster baru.

cd /srv/immich
docker compose pull
docker compose create
docker start immich_postgres
docker exec immich_postgres pg_isready --username=postgres

pg_isready mencetak accepting connections setelah penyiapan pertama selesai. Proses ini memerlukan waktu beberapa detik. docker compose create membangun semua container tanpa menjalankannya. Itulah tujuan langkah ini: server Immich belum boleh berjalan. Server yang berjalan terhadap database kosong akan menerapkan migration, membuat schema baru, dan meminta Anda membuat akun admin baru. Setelah itu, Anda akan memulihkan dump ke bawah aplikasi yang sedang berjalan.

Pulihkan dump.

gunzip --stdout /restore/srv/immich/backup/immich.sql.gz \
  | sed "s/SELECT pg_catalog.set_config('search_path', '', false);/SELECT pg_catalog.set_config('search_path', 'public, pg_catalog', true);/g" \
  | docker exec -i immich_postgres psql --dbname=immich --username=postgres \
      --single-transaction --set ON_ERROR_STOP=on

Dua bagian dalam perintah tersebut menjalankan fungsi penting. sed diperlukan karena pg_dump menulis search_path kosong ke dalam output sebagai langkah keamanan. Dengan demikian, nama tanpa kualifikasi dalam dump tidak dapat merujuk ke schema yang tidak diharapkan. Tipe untuk pencarian vektor Immich berada di public. Dengan search path kosong, proses pemulihan mencapai kolom pertama yang dideklarasikan dengan tipe vector, lalu psql berhenti dengan ERROR: type "vector" does not exist. Menambahkan kembali public ke search path akan memperbaikinya.

--single-transaction --set ON_ERROR_STOP=on membungkus seluruh proses pemulihan dalam satu transaction yang dibatalkan saat error pertama terjadi. Hasilnya adalah database yang pulih sepenuhnya atau database yang tidak berubah. Tanpa opsi tersebut, kegagalan di tengah proses dapat meninggalkan database yang masih dapat dijalankan dan menerima login Anda, tetapi kehilangan sejumlah album yang tidak diketahui. Masalah ini mungkin baru diketahui beberapa minggu kemudian.

Sekarang jalankan semuanya.

docker compose up -d
docker compose ps
docker logs -f immich_server

Tunggu hingga muncul baris startup seperti Immich Server is listening on. Kemudian buka port 2283 dan login menggunakan kredensial lama Anda karena akun pengguna ikut dipulihkan bersama dump. Jika halaman login justru meminta Anda membuat akun admin pertama, berarti database belum dipulihkan. Hentikan proses dan baca kembali output psql.

Perhatikan satu hal tentang petunjuk pemulihan resmi yang diawali dengan docker compose down -v. -v menghapus named volume. Pada compose file bawaan, UPLOAD_LOCATION dan DB_DATA_LOCATION adalah bind mount sehingga tetap ada. Jika salah satunya Anda ubah menjadi named volume, perintah tersebut akan menghapus foto Anda. Baca compose file sebelum menjalankan perintah itu.

Mengapa timeline kosong setelah pemulihan

Timeline dibuat dari baris database. Immich tidak pernah menelusuri upload/ saat boot untuk menemukan kembali foto, karena file tanpa baris database tidak memiliki pemilik, tanggal, atau album. Jadi, pemulihan yang paling sering bermasalah adalah file sudah dipulihkan, tetapi database hilang. Immich berjalan, membuat skema kosong, lalu memberi Anda instance yang berfungsi tetapi tidak berisi apa pun, sementara disk penuh dengan foto Anda. Tidak ada yang hilang. Namun, tidak ada yang dapat ditampilkan. Solusinya adalah menjalankan kembali dump saat server dihentikan, persis seperti di atas.

Versi kedua lebih sulit dideteksi. Database berhasil dipulihkan, timeline terisi entri, tetapi setiap aset gagal dibuka. Artinya, baris database menunjuk ke file yang tidak dapat dilihat oleh container. Biasanya ini terjadi karena library, upload, dan profile berada satu tingkat terlalu dalam setelah sebuah restic restore --target /restore yang tidak dipindahkan ke lokasi yang benar. Periksa dari dalam container, bukan dengan menebak:

docker exec immich_server ls /data

File compose bawaan me-mount UPLOAD_LOCATION ke /data, sehingga daftar tersebut seharusnya menampilkan library, upload, dan profile. Jika yang ditampilkan adalah direktori kosong atau folder srv yang tidak semestinya ada, bind mount Anda mengarah ke tingkat direktori yang salah dan baris database tersebut tidak bermasalah.

Kecocokan versi antara backup dan pemulihan

Immich sering merilis versi baru, dan schema ikut berubah. Karena itu, dump membawa schema dari server yang membuatnya.

Memulihkan dump yang lebih lama ke server yang lebih baru biasanya berhasil karena server menerapkan migration yang masih tertunda saat start, lalu memperbarui schema secara bertahap. Jalur ini diuji di sepanjang urutan rilis. Masalah biasanya muncul saat beberapa versi mayor dilewati sekaligus. Project mempertahankan perubahan yang tidak kompatibel pada rilis mayor dan mendokumentasikannya dalam changelog.

Memulihkan dump yang lebih baru ke server yang lebih lama sama sekali tidak berhasil. Dump tersebut berisi tabel dan kolom yang tidak dikenali oleh kode versi lama. Immich juga menyatakan bahwa downgrade tidak didukung, bahkan di antara versi patch. Tidak ada command rollback yang dapat digunakan.

Jadi, pemulihan yang aman harus dilakukan secara sederhana. Jalankan versi yang sama persis dengan versi yang membuat dump, pulihkan dump tersebut, login, lalu pastikan timeline sudah lengkap. Setelah itu, lakukan upgrade. Upgrade satu rilis setiap kali, dengan menaikkan IMMICH_VERSION dan menjalankan docker compose pull && docker compose up -d setelah setiap peningkatan. Menyimpan dump selama satu minggu juga membantu. Jika dump terbaru ternyata dibuat saat upgrade gagal, dump dari kemarin masih tersedia di repository.

Verifikasi backup setiap bulan

Backup yang belum pernah dipulihkan hanyalah perkiraan. Sebulan sekali, pulihkan backup tersebut ke instance sementara yang dapat dibuang, lalu lihat sebuah foto. Latihan ini memerlukan waktu sekitar twenty minutes dan merupakan satu-satunya cara untuk mengubah seluruh isi halaman ini menjadi rencana pemulihan.

restic snapshots
restic stats latest

snapshots harus menampilkan eksekusi tadi malam. stats latest harus melaporkan ukuran yang mendekati ukuran library Anda, bukan hanya beberapa megabyte.

Pulihkan ke direktori sementara, idealnya pada host cadangan:

restic restore latest --target /tmp/immich-drill

Salin docker-compose.yml dan .env dari set yang dipulihkan, lalu ubah tiga hal pada salinan tersebut. Arahkan UPLOAD_LOCATION dan DB_DATA_LOCATION ke direktori di bawah /tmp/immich-drill. Publikasikan port web di lokasi lain, yaitu 12283:2283, bukan 2283:2283. Hapus baris container_name: karena file compose bawaan menetapkan nama seperti immich_server secara hard-code. Akibatnya, stack kedua pada host yang sama bertabrakan dengan stack pertama dan Docker menolak membuatnya.

Jalankan urutan pemulihan dari bagian sebelumnya: database saja, putar ulang dump, lalu docker compose up -d. Sekarang lakukan empat pemeriksaan berikut untuk membuktikan bahwa pemulihan berhasil.

  1. Login dengan password yang Anda gunakan sebelum latihan. Akun yang dapat digunakan berarti dump berhasil dipulihkan.
  2. Buka timeline dan gulir ke bulan paling lama. Aset yang mencakup seluruh rentang tanggal berarti semua baris telah dipulihkan, bukan hanya data terbaru.
  3. Buka satu foto dalam ukuran penuh dan unduh file aslinya.
  4. Bandingkan file tersebut dengan file yang sama di library aktif menggunakan sha256sum. Hash yang cocok berarti byte tetap utuh setelah melewati proses pemulihan dengan restic.

Kemudian hapus lingkungan latihan menggunakan docker compose down -v di direktori latihan dan hapus /tmp/immich-drill. Catat tanggalnya di tempat yang mudah Anda lihat karena manfaat latihan ini sepenuhnya bergantung pada pelaksanaannya kembali bulan depan. Jika Anda masih menentukan server foto yang akan digunakan, perbandingan PhotoPrism dan Immich membahas perbedaan keduanya secara khusus dalam hal ini.

FAQ

Apakah saya harus menghentikan Immich untuk membuat backup?

Hentikan immich_server dan biarkan immich_postgres tetap berjalan. Database tidak perlu dijeda karena pg_dump membaca di dalam satu snapshot MVCC dan melihat satu keadaan yang konsisten, terlepas dari proses lain yang sedang menulis. File adalah alasan server perlu dihentikan: server menulis upload baru dan job template storage memindahkan file antar-direktori, sehingga tool backup dapat membaca file saat penulisan belum selesai dan menyimpan salinan yang terpotong tanpa error. Menjalankan docker stop immich_server sebelum snapshot dan docker start immich_server setelahnya menghilangkan kondisi balapan tersebut.

Apakah saya dapat menyalin folder data Postgres alih-alih menjalankan pg_dump?

Tidak. Penyalinan bertahap atas direktori data yang sedang aktif membaca file pada waktu yang berbeda, sehingga hasilnya bukan satu keadaan yang konsisten. Postgres akan menolaknya saat startup dengan PANIC: could not locate a valid checkpoint record atau gagal kemudian karena terdapat page yang rusak. Bahkan salinan yang dibuat saat seluruh layanan dihentikan tetap terikat pada build database yang persis sama: Immich menetapkan image Postgres 14 dengan versi extension vector-search tertentu, dan direktori tersebut tidak akan terbuka pada lingkungan lain. SQL dump berupa teks biasa dan dapat dipulihkan ke server yang kompatibel.

Mengapa timeline Immich saya kosong setelah restore?

Karena timeline dibangun dari baris database, sedangkan Anda memulihkan file tanpa database. Immich tidak pernah memindai upload/ untuk menemukan kembali foto, sehingga file tanpa baris database tetap tidak terlihat. Foto itu sendiri tidak berubah. Hentikan server, replay dump ke Postgres yang baru diinisialisasi, lalu start stack. Jika timeline justru terisi tetapi setiap foto gagal dibuka, masalahnya terbalik: library, upload, dan profile tidak berada langsung di dalam direktori yang di-bind ke container. Periksa dengan docker exec immich_server ls /data.

Folder Immich mana yang dapat saya lewati dalam backup?

thumbs dan encoded-video dapat dibuat ulang dari file asli, sedangkan DB_DATA_LOCATION dapat dibangun ulang dari dump. Karena itu, folder-folder tersebut tidak perlu dimasukkan ke dalam set backup. Melewatkannya berarti menggunakan waktu setelah restore, bukan storage sebelum restore, karena pembuatan ulang preview dan transcode untuk library besar dapat memerlukan CPU selama berjam-jam. Proses ini dijalankan dari Administration > Jobs untuk asset yang hilang. Yang tidak boleh dilewati adalah library, upload, dan profile karena ketiganya menyimpan satu-satunya salinan setiap file asli.

Apakah saya dapat memulihkan dump Immich ke versi yang lebih baru?

Biasanya bisa karena server menerapkan migration yang tertunda saat start dan memajukan schema secara bertahap. Arah sebaliknya gagal: Immich tidak mendukung downgrade, bahkan antar-patch release. Karena itu, dump dari release yang lebih baru tidak dapat dimuat ke server yang lebih lama. Lakukan restore dengan IMMICH_VERSION yang ditetapkan ke release yang membuat dump tersebut, pastikan timeline lengkap, lalu lakukan upgrade. Catat versi di samping setiap dump menggunakan docker inspect --format '{{.Config.Image}}' immich_server karena nilai default IMMICH_VERSION=v3 adalah tag yang dapat berubah dan tidak memberikan informasi versi.