SSD Nodes Learn Hosting plans →
Rehberler Matt ConnorYazan Matt Connor

Immich VPS yedeği nasıl alınır ve geri yüklenir

Immich yedeği alırken Postgres veritabanı dökümü, UPLOAD_LOCATION klasörü ve docker-compose dosyalarının neden bir bütün olması gerektiğini öğrenin. Zaman çizelgesi boş kalmasın.

Bir Immich yedeğinin içermesi gerekenler

Bir Immich yedeği, aynı anda yakalanmış üç öğeden oluşur. UPLOAD_LOCATION altındaki orijinal dosyalar, Postgres veritabanının bir SQL dökümü ve yığını tanımlayan .env ile docker-compose.yml dosyaları. Geri yükleme işlemi, Immich sunucusu durdurulmuşken bu dökümün temiz bir veritabanına aktarılmasını ve yığının geri kalanının ancak bundan sonra başlatılmasını gerektirir. Sıralamayı yanlış yaparsanız, dolu bir disk üzerinde boş bir zaman çizelgesi gösteren çalışan bir Immich ile karşılaşırsınız.

Bu ayrım önemlidir çünkü Immich, durumunu birbirlerinden habersiz iki farklı yerde tutar. Postgres; her albümü, yüz kümesini, paylaşılan bağlantıyı, kullanıcı hesabını, API anahtarını ve her varlığın depolanan yolunu barındırır. Dosya sistemi ise pikselleri tutar. Dosyaları veritabanı olmadan geri yüklerseniz Immich size hiçbir şey göstermez. Veritabanını dosyalar olmadan geri yüklerseniz, her varlık bozuk bir görsel olarak açılır.

Buradaki komutlar, 2026 Ağustos ayı başındaki güncel sürüm olan Immich v3.1.0 temel alınarak yazılmıştır. 21-10-2026 itibarıyla güncel sürüm, 20-10-2026 tarihinde yayınlanan v3.3.4'tür ve compose dosyası, veritabanı imajı ile belgelenen yedekleme ve geri yükleme adımları bu sayfada kullanılanlarla uyumludur. Proje hızlı güncellenir ve belgelenen yedekleme prosedürü birden fazla kez değişmiştir; bu nedenle herhangi bir komutu kopyalamadan önce kullandığınız sürümü kontrol edin. Yığın henüz çalışmıyorsa, Immich kurulum kılavuzu ile başlayın ve ardından buraya dönün.

Yolların neyi işaret ettiğini bilin

Bu sayfadaki her şeyi iki değişken belirler: .env. UPLOAD_LOCATION, Immich'in tüm medya dosyalarını içine yazdığı üst dizindir. DB_DATA_LOCATION ise Postgres veri dizinidir.

Varsayılan example.env ayarı UPLOAD_LOCATION=./library değerini atar; bu kafa karıştırıcı bir varsayılandır çünkü Immich bunun içinde library adında bir klasör oluşturur. Orijinal dosyalarınız ./library/library konumunda biter. Bunun yerine mutlak bir yol belirleyin; böylece bir yedekleme betiği, onu hangi dizinden çalıştırdığınıza asla bağımlı kalmaz.

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

Immich, UPLOAD_LOCATION içinde çeşitli klasörler oluşturur. Bunlardan üçü, hiçbir işlemin yeniden oluşturamayacağı verileri tutar:

  • library: depolama şablonunuza göre düzenlenmiş orijinal dosyalar
  • upload: henüz şablon düzenine taşınmamış orijinal dosyalar ve yükleme aşamasındaki veriler
  • profile: kullanıcı profil resimleri

library dizinini kaybederseniz fotoğraf da gider. Immich, orijinal dosyanın ikinci bir kopyasını hiçbir yerde tutmaz.

Postgres veri dizinini kopyalamanın neden yedekleme sayılmadığı

DB_DATA_LOCATION kolay bir hedef gibi görünür. Bir dizindir, rsync onu kopyalar ve kopyalama işlemi hatasız tamamlanır. Eğer Postgres çalışırken kopyalarsanız, bu bir yedekleme değildir. Postgres durdurulmuş haldeyken kopyalarsanız, bu bir yedeklemedir ancak oldukça kırılgandır. İşte bunun iki nedeni ve her ikisinin de nasıl başarısız olduğunu gözlemleyebilirsiniz.

Birincisi veri tutarsızlığıdır (tearing). Postgres her değişikliği önce write-ahead log (WAL) dosyasına yazar, ardından bir checkpoint sırasında tablo dosyalarına uygular. Dolayısıyla herhangi bir anda diskteki dosyalar işlem halindedir ve dört dakika süren bir kopyalama işlemi, ilk dosyayı 02:00'de, sonuncusunu ise 02:04'te okur. Bu iki dosya aynı işleme ait değildir. Postgres'i bu sonuç üzerinde başlattığınızda, ya PANIC: could not locate a valid checkpoint record hatasıyla açılışta reddeder ya da başlar ve hasarlı bir sayfayı ilk okuduğunda invalid page in block 1234 of relation base/16384/... hatasıyla çöker. Her iki durumda da bu kopyadan kurtarma yapmak mümkün değildir.

İkinci neden, her şey durdurulmuşken aldığınız kopyayla ilgilidir. PostgreSQL, kapatılmış bir veri dizininin tam kopyasını geçerli bir yedek olarak kabul eder, ancak bu dizin yalnızca depolama formatını paylaşan ikili dosyalarla açılabilir. Immich, veritabanı imajını digest değeriyle sabitler, bu değer şu an ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0'dır. Bu, içerisinde VectorChord, pgvector ve pgvecto.rs vektör arama eklentileri derlenmiş Postgres 14 sürümüdür. Daha sonraki bir Postgres 14 ara sürümü dizini olduğu gibi açabilir, ancak farklı bir Postgres ana sürümü bunu yapamaz. Tablolarınızın bağlı olduğu eklentilerin de uyumlu sürümlerde mevcut olması gerekir. Geri yükleme yapacağınız sunucunun uyumlu bir imaj çalıştırması şarttır. Bir SQL dump ise bundan etkilenmez: metin tabanlıdır ve uyumlu herhangi bir sunucu tarafından tekrar işlenebilir.

pg_dump, veri tutarsızlığı sorununu doğrudan ortadan kaldırır. Tüm veritabanını tek bir MVCC (çok sürümlü eşzamanlılık denetimi) anlık görüntüsü içinde okur; böylece diğer yazma işlemleri devam ederken veritabanını tam olarak tek bir andaki haliyle görür. Postgres'i dump almak için durdurmanıza gerek kalmamasının nedeni budur.

Yedekleme dışında bırakabilecekleriniz

Bunlar yeniden oluşturulabildiği için yedeklemeyi atlayabilirsiniz:

  • thumbs: önizleme ve küçük resimler
  • encoded-video: dönüştürülmüş videolar
  • DB_DATA_LOCATION: dökümden yeniden oluşturulabilir
  • model-cache Docker volume: makine öğrenimi modelleri, ihtiyaç duyulduğunda tekrar indirilir

Bunları atlamak bir kazanç değil, bir tercihtir. Büyük bir kütüphane için küçük resimleri ve videoları yeniden oluşturmak, küçük bir VPS üzerinde saatlerce CPU kullanımı gerektirir ve bu süre zarfında zaman çizelgesi gri yer tutucular gösterir. Bunları Administration > Jobs menüsünden, "Generate Thumbnails" ve "Transcode Videos" seçeneklerini eksik varlıklar üzerinde çalışacak şekilde ayarlayarak yeniden başlatabilirsiniz. Yedekleme hedefinizde yer varsa bunları dahil edin ve bekleme süresinden kurtulun. Depolama sınırınıza yakınsanız bunları çıkarın ve yeniden oluşturma süreci için plan yapın. Immich kütüphanesi boyutlandırma konusu, bu klasörlerin orijinallere kıyasla ne kadar büyüdüğünü açıklar.

Bir klasörden daha bahsetmekte fayda var. UPLOAD_LOCATION/backups, Immich'in kendi otomatik veritabanı dökümlerini tutar; her gün 02:00'de yazılır ve son 14 tanesi saklanır, bu ayar Administration > Settings > Database Dump Settings altından yapılandırılabilir. Bunların size bir maliyeti yoktur ve oldukça kullanışlıdırlar. Ancak bu dökümler, korudukları kütüphane ile aynı diskte yer aldıkları için hatalı bir taşıma işleminde yardımcı olurlar, çöken bir sunucuda ise işe yaramazlar. Yine de kendi dökümünüzü alın, çünkü bizzat tetiklediğiniz bir döküm, onunla eşleşen dosya anlık görüntüsüyle aynı anda alınmış olur.

Veritabanı dökümünü alma

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

immich ve postgres değerlerini, eğer değiştirdiyseniz kendi DB_DATABASE_NAME ve DB_USERNAME bilgilerinizle değiştirin. --clean --if-exists, her CREATE ifadesinin önüne bir DROP ... IF EXISTS ekler; böylece döküm, ilk nesnede durmak yerine halihazırda nesneler barındıran bir veritabanına yeniden işlenebilir.

Şimdi yedekleme betiklerini sessizce bozan o detaya gelelim. Bu komut bir boru hattıdır (pipeline) ve kabuk, boru hattındaki son komutun çıkış durumunu raporlar. Eğer pg_dump hatalı bir parola veya çalışmayan bir container nedeniyle başarısız olursa, gzip boş bir akış alır, mükemmel derecede geçerli bir gzip dosyası yazar ve 0 çıkış koduyla sonlanır. Betiğiniz başarı raporu verir ancak elinizde 20 baytlık bir yedek dosyası kalır. Her yedekleme betiğinin en üstüne pipefail ekleyin:

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

Ardından çıkış koduna güvenmek yerine sonucu kontrol edin:

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

Sağlıklı bir dökümün ilk satırı -- PostgreSQL database dump ifadesini içerir. Birkaç yüz baytlık bir dosya, betik ne rapor ederse etsin başarısız bir dökümdür.

Çalışan sunucuya sorarak dökümü hangi sürümün oluşturduğunu dökümün yanına kaydedin:

curl -fsS http://localhost:2283/api/server/version > /srv/immich/backup/immich-version.txt

Bu uç nokta giriş gerektirmez ve çalışan sürümü major, minor ve patch numaraları olarak döndürür; yani 3, 1 ve 0, v3.1.0 anlamına gelir. Bunun için .env ifadesine veya yalnızca yapılandırdığınız imaj referansını yansıtan docker inspect --format '{{.Config.Image}}' immich_server ifadesine güvenmeyin. Stok dosya, her 3.x sürümünü takip eden değişken bir etiket olan IMMICH_VERSION=v3 değerini ayarlar; bu nedenle :v3 ile biten bir kayıt, dökümü hangi derlemenin oluşturduğu hakkında size hiçbir bilgi vermez. .env içindeki etiketi de sabitleyin.

Sunucuyu duraklatın ve restic ile anlık görüntü alın

UPLOAD_LOCATION altındaki dosyalar, Immich çalışırken değişmez değildir. Sunucu yeni yüklemeleri yazar ve depolama şablonu işi dosyaları dizinler arasında taşır. Bir yedekleme aracı bir dosyayı yazma işlemi sırasında okursa, o baytları dosyanın tamamıymış gibi depolar ve hiçbir hata rapor edilmez. Çalışma süresi boyunca sunucu container'ını durdurun:

docker stop immich_server

immich_postgres çalışmaya devam etmelidir, çünkü döküm işlemi buna ihtiyaç duyar. Sunucuyu tekrar başlatana kadar web arayüzü ve mobil uygulama çevrimdışı kalacaktır; ev tipi bir kurulumda saat 03:00'te bu genellikle sorun yaratmaz.

restic, verileri sunucudan çıkmadan önce tekilleştirdiği ve şifrelediği için bu senaryoya uygundur. Aracı, bu sunucuda bulunmayan bir depoya yönlendirin:

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

Nesne depolama (object storage) aynı şekilde çalışır ve kopyayı tamamen kendi donanımınızın dışına çıkarmak istiyorsanız daha iyi bir çözümdür:

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

Bu uç nokta, ikinci bir makinede kendinizin çalıştırdığı bir MinIO bucket'ı veya S3 uyumlu herhangi bir sağlayıcı olabilir. Kütüphane ile aynı disk üzerindeki bir depo, sizi yalnızca yanlışlıkla silme işlemine karşı korur, başka hiçbir şeye karşı korumaz.

Ardından, tam olarak neyin önemli olduğunu belirterek anlık görüntüyü alın:

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 her çalışmada tüm ağacı okur ancak yalnızca daha önce görmediği blokları yükler; bu nedenle ilk anlık görüntü tüm kütüphanenizi taşır, sonraki her anlık görüntü ise yalnızca o günün yeni fotoğraflarını taşır.

Saklama politikası ve başka bir yerde tutulması gereken anahtarlar

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

forget, snapshot'ları dizinden kaldırır. --prune ise bu snapshot'ların son referans olduğu verileri silen kısımdır. forget komutunu --prune bayrağı olmadan çalıştırırsanız depolama maliyetiniz asla düşmez.

Yapı kontrolleri düşük maliyetlidir, bu nedenle haftalık olarak çalıştırın:

restic check

Bu komut, depo meta verilerinin tutarlı olduğunu doğrular. Verilerinizi okumaz. Ayda bir kez, bir örneklem veriyi yeniden okuyun ve kayıtlı hash değerleriyle karşılaştırın:

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

Depolama arka ucundaki sessiz bozulmaları yakalayan tek kontrol budur; çünkü gerçek blokları indirir ve sağlama toplamlarını (checksum) yeniden hesaplar. Bir fotoğraf kütüphanesi üzerinde tam bir --read-data işlemi, tüm deponun indirilmesi anlamına gelir. Bu durum, ücretli nesne depolama (object storage) hizmetlerinde gerçek maliyet yaratır; bu nedenle kullanıcılar genellikle dönemsel bir alt küme üzerinde kontrol yapmayı tercih eder.

Şimdi insanların atladığı kısım: Bir restic depo parolası kurtarılamaz. Parola sıfırlama veya destek talebi oluşturma imkanı yoktur. Eğer parolanın tek kopyası, geri yüklemeye çalıştığınız sunucudaki /root/.restic-password içinde bulunuyorsa, yedekleriniz şifreli gürültüden ibarettir. Aynı durum nesne depolama erişim anahtarı ve .env içindeki DB_PASSWORD için de geçerlidir. Bunların hepsini, bu makinenin çalışır durumda olmasına bağlı olmayan bir yerde saklayın: çıktısını alıp bir çekmeceye koyun veya farklı bir donanımda çalışan bir parola yöneticisinde tutun. Eğer bu yönetici de self-hosted ise aynı muameleye ihtiyaç duyar ve Vaultwarden yedekleme işlemi başlı başına ayrı bir görevdir.

Immich'i doğru sırada geri yükleme

Geri yükleme sırası, iyi yedeklerin boş zaman çizelgelerine dönüştüğü noktadır. Yeni sunucuda bu sırayı izleyin.

Önce yapılandırmayı geri alın. Bu, hangi sürümü çalıştıracağınızı ve yolların nereyi işaret ettiğini size söyler.

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

Başlamadan önce sürümü sabitleyin. immich-version.txt dosyasını okuyun, .env içindeki IMMICH_VERSION değerini tam olarak o sürüme (ana sürüm 3, alt sürüm 1, yama 0 için v3.1.0) ayarlayın ve şimdilik en yeni sürümü kullanmayın. Immich, yama sürümleri arasında bile olsa sürüm düşürmeyi desteklemez; bu nedenle daha yeni bir sunucu eski bir döküm üzerinde çalışıp migrasyonlarını gerçekleştirirse geri dönüş yolu kalmaz.

Medya dosyalarını geri yükleyin.

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

Ardından library, upload ve profile dosyalarını, bu sunucuda UPLOAD_LOCATION'in işaret ettiği dizinin içine doğrudan yerleşecek şekilde taşıyın. Sunucu yolu değişebilir çünkü compose dosyası bu dizini container içindeki sabit bir yola bağlar. İçerideki düzen değişemez.

Veritabanını tek başına başlatın. Postgres'in temiz bir küme oluşturması için DB_DATA_LOCATION kısmını boş bırakın.

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

pg_isready, ilk kurulum tamamlandığında (bu birkaç saniye sürer) accepting connections çıktısını verir. docker compose create, tüm container'ları başlatmadan oluşturur ve bu adımın tüm amacı budur: Immich sunucusu henüz çalışmamalıdır. Boş bir veritabanına karşı başlatılan bir sunucu, migrasyonlarını uygular, yeni bir şema oluşturur ve sizden yeni bir yönetici hesabı oluşturmanızı ister; bu durumda çalışan bir uygulama üzerinde döküm geri yüklemesi yapmış olursunuz.

Dökümü geri yükleyin.

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

Bunun iki parçası fiili işi yapar. sed gereklidir çünkü pg_dump, güvenlik önlemi olarak çıktısına boş bir search_path yazar; böylece dökümdeki nitelenmemiş isimler beklenmedik bir şemaya çözümlenemez. Immich'in vektör arama türleri public içinde yer alır; bu nedenle boş bir arama yoluyla geri yükleme, vektör türüyle tanımlanmış ilk sütuna ulaştığında psql ERROR: type "vector" does not exist hatasıyla durur. public değerini yola geri eklemek bu sorunu çözer.

--single-transaction --set ON_ERROR_STOP=on, tüm geri yükleme işlemini ilk hatada duran tek bir işlem (transaction) içine alır. Ya eksiksiz bir veritabanına ya da hiç dokunulmamış bir veritabanına sahip olursunuz. Bu olmadan, yarıda kalan bir hata, çalışan ancak giriş yaptığınızda haftalar sonra fark edeceğiniz eksik albümler içeren bir veritabanı bırakır.

Şimdi her şeyi başlatın.

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

Immich Server is listening on gibi bir başlangıç satırı bekleyin, ardından 2283 numaralı portu açın ve eski kimlik bilgilerinizle giriş yapın; çünkü kullanıcı hesapları dökümle birlikte geri gelmiştir. Giriş sayfası bunun yerine ilk yönetici hesabını oluşturmanızı isterse, veritabanı geri yüklenmemiş demektir. Durun ve psql çıktısını tekrar okuyun.

Resmi komut satırı geri yükleme talimatları hakkında bir uyarı: bu talimatlar docker compose down -v ile başlar. -v komutu adlandırılmış volume'leri kaldırır. Standart compose dosyasında UPLOAD_LOCATION ve DB_DATA_LOCATION bind mount'tur, bu yüzden silinmezler. Eğer bunlardan birini adlandırılmış volume olarak değiştirdiyseniz, bu komut fotoğraflarınızı siler. Komutu çalıştırmadan önce compose dosyanızı okuyun.

Geri yükleme sonrasında zaman çizelgesi neden boş

Zaman çizelgesi veritabanı satırlarından oluşturulur. Immich, fotoğrafları yeniden keşfetmek için açılışta asla upload/ dizinini taramaz; çünkü veritabanı satırı olmayan bir dosyanın sahibi, tarihi ve albümü yoktur. Bu nedenle en yaygın hatalı geri yükleme senaryosu, dosyaların geri getirilip veritabanının eksik bırakılmasıdır. Immich başlar, boş bir şema oluşturur ve disk fotoğraflarınızla dolu olmasına rağmen size içinde hiçbir şey olmayan çalışan bir örnek sunar. Hiçbir şey kaybolmamıştır ancak hiçbir şey görünür de değildir. Çözüm, sunucu durdurulmuş haldeyken dökümü yukarıda belirtildiği şekilde yeniden yüklemektir.

İkinci senaryo daha sessizdir. Veritabanı geri yüklenir, zaman çizelgesi girdilerle dolar ancak hiçbir varlık (asset) açılmaz. Bu durum, satırların container'ın göremediği dosyalara işaret ettiği anlamına gelir; genellikle restic restore --target /restore komutundan sonra library, upload ve profile dizinlerinin bir seviye daha derinde kalmasından kaynaklanır. Tahmin yürütmek yerine container içinden kontrol edin:

docker exec immich_server ls /data

Standart compose dosyası UPLOAD_LOCATION dizinini /data konumuna bağlar (mount), bu nedenle listeleme işlemi library, upload ve profile dizinlerini göstermelidir. Eğer boş bir dizin veya fazladan bir srv klasörü görünüyorsa, bind mount işleminiz yanlış seviyeyi işaret ediyordur ve veritabanı satırlarınız aslında doğrudur.

Yedek ve geri yükleme arasında sürüm uyumu

Immich sık sık yeni sürümler yayınlar ve veritabanı şeması bu sürümlerle birlikte değişir; bu nedenle bir dump dosyası, onu oluşturan sunucunun şema yapısını taşır.

Eski bir dump dosyasını daha yeni bir sunucuya geri yüklemek genellikle çalışır; çünkü sunucu, başlatma sırasında bekleyen migrasyonları uygular ve şemayı ileriye taşır. Bu yol, sürüm dizisi boyunca test edilmiştir. Sorun, tek adımda birden fazla ana sürüm atlandığında ortaya çıkar; proje, köklü değişiklikleri ana sürümlere saklar ve bunları değişiklik günlüğünde (changelog) belgeler.

Daha yeni bir dump dosyasını daha eski bir sunucuya geri yüklemek ise kesinlikle çalışmaz. Dump dosyası, eski kodun tanımadığı tablo ve sütunlar içerir. Immich, yama sürümleri arasında dahi sürüm düşürmenin (downgrade) desteklenmediğini belirtir. Başvurulabilecek bir geri alma (rollback) komutu bulunmamaktadır.

Bu nedenle güvenli geri yükleme yöntemi standart olandır. Dump dosyasını oluşturan sürümün aynısını çalıştırın, veriyi geri yükleyin, giriş yapın, zaman çizelgesinin eksiksiz olduğunu doğrulayın ve ancak bundan sonra yükseltme yapın. Her seferinde tek bir sürüm yükseltin, IMMICH_VERSION değerini güncelleyin ve her yükseltmeden sonra docker compose pull && docker compose up -d komutunu çalıştırın. Bir haftalık dump dosyalarını saklamak bu noktada yardımcı olur: Eğer en yeni dump dosyasının hatalı bir yükseltme sırasında alındığı ortaya çıkarsa, dünkü yedeğiniz hala deponuzda duruyor olacaktır.

Yedekleri her ay doğrulayın

Geri yüklemesini hiç yapmadığınız bir yedek, sadece bir tahmindir. Ayda bir kez yedeği geçici bir sunucuya geri yükleyin ve bir fotoğrafa bakın. Bu tatbikat yaklaşık yirmi dakika sürer ve bu sayfanın geri kalanını bir kurtarma planına dönüştüren tek şey budur.

restic snapshots
restic stats latest

snapshots, dün geceki çalışmayı listelemelidir. stats latest, birkaç megabayt değil, kütüphanenize yakın bir boyut bildirmelidir.

İdeal olarak yedek bir sunucuda, geçici bir dizine geri yükleme yapın:

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

docker-compose.yml ve .env dosyalarını geri yüklenen kümeden kopyalayın, ardından kopyadaki üç şeyi değiştirin. UPLOAD_LOCATION ve DB_DATA_LOCATION değerlerini /tmp/immich-drill altındaki dizinlere yönlendirin. Web portunu başka bir yere, 2283:2283 yerine 12283:2283 olarak yayınlayın. container_name: satırlarını silin; çünkü standart compose dosyası immich_server gibi isimleri sabit kodlar, bu yüzden aynı sunucudaki ikinci bir yığın ilkiyle çakışır ve Docker oluşturmayı reddeder.

Yukarıdaki geri yükleme sırasını çalıştırın: sadece veritabanı, dump dosyasını tekrar oynatın, ardından docker compose up -d komutunu kullanın. Şimdi bir şeylerin çalıştığını kanıtlayan dört kontrolü yapın.

  1. Tatbikattan önce kullandığınız şifreyle giriş yapın. Çalışan hesaplar, dump dosyasının başarıyla geri yüklendiği anlamına gelir.
  2. Zaman çizelgesini açın ve en eski aya gidin. Tüm tarih aralığındaki varlıklar, sadece son verilerin değil, tüm satırların geri geldiği anlamına gelir.
  3. Bir fotoğrafı tam boyutta açın ve orijinalini indirin.
  4. sha256sum ile canlı kütüphanenizdeki aynı dosya ile karşılaştırın. Eşleşen hash değerleri, baytların restic üzerinden gidiş-dönüş sürecinde bozulmadan kaldığı anlamına gelir.

Ardından tatbikat dizininde docker compose down -v ile sistemi kapatın ve /tmp/immich-drill dizinini silin. Tarihi görebileceğiniz bir yere not edin, çünkü bunun değeri tamamen önümüzdeki ay tekrar yapılmasına bağlıdır. Hangi fotoğraf sunucusunu kullanacağınıza hala karar veriyorsanız, PhotoPrism ve Immich karşılaştırması bu iki yazılımın tam olarak bu konuda nasıl farklılaştığını ele almaktadır.

FAQ

Immich'i yedeklemek için durdurmam gerekiyor mu?

immich_server servisini durdurun ve immich_postgres servisini çalışır durumda bırakın. Veritabanının duraklatılmasına gerek yoktur; çünkü pg_dump, MVCC anlık görüntüsü (snapshot) üzerinden okuma yapar ve başka işlemler yazıyor olsa dahi tek bir tutarlı anı görür. Dosyalar, durdurma işleminin gerekçesidir: Sunucu yeni yüklemeleri yazar ve depolama şablonu işi dosyaları dizinler arasında taşır; bu nedenle bir yedekleme aracı, dosya yazılma aşamasındayken okuma yapabilir ve hatalı bir şekilde eksik (truncated) bir kopya alabilir. Anlık görüntüden önce docker stop immich_server ve sonrasında docker start immich_server komutlarını çalıştırmak, bu yarış durumunu (race condition) ortadan kaldırır.

pg_dump çalıştırmak yerine Postgres veri klasörünü kopyalayabilir miyim?

Postgres çalışırken bu işlem yapılamaz. Canlı bir veri dizininin anlık kopyası, farklı dosyaları farklı zamanlarda okur; bu nedenle sonuç tutarlı bir durum oluşturmaz ve Postgres bunu başlatma sırasında PANIC: could not locate a valid checkpoint record hatası ile reddeder veya daha sonra hasarlı bir sayfa nedeniyle başarısız olur. Postgres durdurulmuşken alınan tam bir kopya geçerli bir yedektir, ancak bu kopya yalnızca aynı Postgres ana sürümü ve uyumlu eklentiler altında açılabilir. Immich; VectorChord, pgvector ve pgvecto.rs içeren bir Postgres 14 imajını sabitler (pin) ve bu dizin farklı bir ana sürüm altında açılmaz. SQL dökümü düz metindir ve uyumlu herhangi bir sunucuya tekrar yüklenebilir, bu nedenle saklanması gereken kopya budur.

Geri yükleme sonrasında Immich zaman çizelgem neden boş?

Çünkü zaman çizelgesi veritabanı satırlarından oluşturulur ve siz veritabanı olmadan sadece dosyaları geri yüklediniz. Immich, fotoğrafları yeniden keşfetmek için upload/ dizinini asla taramaz; bu nedenle satırı olmayan dosyalar görünmez kalır. Fotoğrafların kendisi bozulmamıştır. Sunucuyu durdurun, dökümü yeni başlatılmış bir Postgres veritabanına geri yükleyin ve ardından yığını (stack) başlatın. Eğer zaman çizelgesi dolu ancak fotoğrafların hiçbiri açılmıyorsa, sorun tam tersidir: library, upload ve profile dizinleri, konteyner içine bağlanan dizinin doğrudan içinde değildir. Bunu docker exec immich_server ls /data ile kontrol edin.

Yedekleme sırasında hangi Immich klasörlerini atlayabilirim?

thumbs ve encoded-video orijinal dosyalardan yeniden oluşturulabilir, DB_DATA_LOCATION ise dökümden tekrar inşa edilebilir; bu nedenle bunların yedekleme setinde bulunması zorunlu değildir. Bunları atlamak, yedekleme öncesinde depolama alanından tasarruf sağlar ancak geri yükleme sonrasında zaman maliyeti yaratır; çünkü büyük bir kütüphane için önizlemeleri ve kod dönüştürme işlemlerini yeniden oluşturmak saatlerce CPU gücü gerektirir ve Administration > Jobs menüsünden eksik varlıklar için çalıştırılır. Asla atlamamanız gerekenler, her orijinal dosyanın tek kopyasını barındıran library, upload ve profile dizinleridir.

Immich dökümünü daha yeni bir sürüme geri yükleyebilir miyim?

Genellikle evet, çünkü sunucu başlatma sırasında bekleyen migrasyonları uygular ve şemayı ileri taşır. Bunun tersi başarısız olur: Immich, yama sürümleri arasında bile olsa sürüm düşürmeyi (downgrade) desteklemez; bu nedenle daha yeni bir sürümden alınan döküm, daha eski bir sunucuya yüklenemez. Dökümü alan sürümle sabitlenmiş IMMICH_VERSION ile geri yükleme yapın, zaman çizelgesinin tam olduğunu doğrulayın ve ardından yükseltme işlemini gerçekleştirin. Her dökümün yanına curl -fsS http://localhost:2283/api/server/version ile sürüm bilgisini kaydedin; çünkü docker inspect yalnızca yapılandırılmış imaj referansını yansıtır ve varsayılan IMMICH_VERSION=v3 etiketi size hiçbir şey ifade etmeyen değişken bir etikettir.