TrueNAS ile Sıfır Veri Kaybı: Immich Nasıl Taşınır?

Server racks in a data center with blue and orange data flow lines and a technician operating a console

Ev sunucusu (NAS) kullananların en büyük kabuslarından biri, sistem çökmeleri veya disk doluluğu nedeniyle canlıdaki verileri yeni bir sunucuya taşımak zorunda kalmaktır. Hele ki bu veri, içinde binlerce aile anısını, albüm yapılarını ve kullanıcı eşleşmelerini barındıran Immich gibi devasa bir fotoğraf arisviyse süreç daha da stresli bir hal alabilir.

Bu yazıda, eski bir TrueNAS SCALE sunucusunda alanı tamamen dolmuş olan ve web arayüzüne bile erişmekte zorlanan 41.008 adet görsel/videodan (38.923 fotoğraf, 2.085 video) oluşan dev bir Immich arşivini, yeni bir TrueNAS SCALE sunucusuna Docker katmanları ve SSH tünelleri kullanarak nasıl “sıfır veri kaybı” ve “karıştırma riski olmadan” taşıdığımızı, yaşadığımız pratik zorluklarla birlikte adım adım anlatıyoruz.


Senaryo ve Karşılaşılan İlk Zorluklar

Eski sunucumuzun disk alanı %100 dolduğu için sistem kararsızlaşmıştı ve yerel ağda IP adresi sürekli değişiyordu (.195 -> .197 -> .146). Bu durum, sysadmin dünyasının ilk altın kuralını hatırlattı: “Asla varsayımlarla hareket etme, her adımda nerede olduğunu doğrula!”

Verileri taşımak için web arayüzünden sürükle-bırak yapmak 41 bin dosyada tarayıcıyı kilitleyeceği için operasyonu tamamen SSH ve Docker CLI üzerinden yürütmeye karar verdik.

Adım 1: Docker Konteynerinin İçine Sızmak ve Doğru CLI Aracını Bulmak

İlk hedefimiz, eski Immich sunucusuna komut satırından bağlanıp API Key yardımıyla kütüphane durumunu doğrulamaktı.

Eski NAS’a SSH ile bağlandıktan sonra ana Immich konteynerini bulup içine sızdık:

Bash

sudo docker exec -it <konteyner_id> sh

Burada ilk aldığımız hata sh: 1: immich: not found oldu. Immich, mikroservis mimarisiyle çalıştığı için her konteynerin içinde CLI aracı yüklü gelmez. Çözüm olarak Node.js’in npx paket yöneticisinden beslenmek istedik:

Bash

npx immich-cli login http://localhost:3001/api "API_KEY"

Ankara, npm registry dünyasında Immich ekibinin bu aracı @immich/cli ismiyle yayınladığını (E404 hatasıyla) keşfettik. Komutu güncellediğimizde ise karşımıza ECONNREFUSED 127.0.0.1:3001 ağ hatası çıktı.

Alınan Ders (Docker Networking): Konteynerin içindeyken localhost dediğinizde, servis aynı odanın (konteynerin) içinde dinleme yapmıyorsa istek boşa düşer. Docker bridge modunda çalışıyorsa, konteyner içinden dış kapıya dolanmak için sunucunun gerçek yerel IP’sini kullanmak gerekir.

Komutu sunucunun o anki güncel IP’sine yönlendirerek nihayet yeşil ışığı yaktık ve durum raporunu aldık:

Bash

npx @immich/cli login http://192.168.2.146:30041/api "API_KEY"
# Logged in as mkmuratkaya@gmail.com

Adım 2: İki Sunucuyu Dijital İmza (SSH Key) ile Evlendirmek

Eski sunucunun diski tamamen dolu olduğundan, dosyaları kendi içinde sıkıştırıp taşımak diski patlatırdı. Veriyi eski diskte hiç yer kaplamadan doğrudan yeni sunucuya akıtmak için iki sunucu arasında şifresiz, güvenli bir SSH Tüneli inşa etmeliydik.

Eski NAS üzerinde bir dijital imza ürettik:

Bash

ssh-keygen -t ed25519

Ancak bu aşamada sinsi bir hata yaptık ve komutun başına sudo koyduk. Bu yüzden anahtar bizim normal kullanıcımızın (truenas_admin) odasında değil, kök kullanıcının (root) odasında üretildi.

Güvenlik Paradoksu ve Dosya İzinleri

Yeni NAS’a bu anahtarı ssh-copy-id ile göndermek istediğimizde yeni sunucu Permission denied (publickey) hatası verdi. Çünkü yeni sunucu güvenlik gereği şifreyle girişi kapatmıştı; anahtarı eklemek için şifre istiyor, şifre girmek istediğimizde ise “şifre kabul etmiyoruz” diyerek bizi dışarı atıyordu!

Çözüm: Yeni TrueNAS web arayüzüne gidip truenas_admin kullanıcısında varsayılan olarak kapalı gelen “SSH Access” kutucuğunu işaretledik. Bu kutucuk açılınca altından beliren SSH Public Key alanına, eski sunucuda ürettiğimiz anahtarı yapıştırdık.

Yetmedi; Linux’un katı kuralları gereği, anahtarların saklandığı klasörlerin izinlerini (Permissions) sadece sahibinin okuyabileceği şekilde sıkılaştırdık:

Bash

chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

Zsh Kabuğu ve Yıldız (*) Engeli

Anahtarları root odasından kendi kullanıcımızın odasına taşırken Eski NAS’ın varsayılan kabuğu olan Zsh araya girdi. sudo cp /root/.ssh/* ~/.ssh/ komutundaki yıldız karakterini Zsh henüz yetkisi yokken taramaya çalıştığı için zsh: no matches found hatası fırlattı. Dosya isimlerini tek tek açıkça yazarak bu engeli de aştık ve nihayet sudosuz olarak yeni sunucunun disk yapısını listelemeyi başardık:

Bash

ssh truenas_admin@192.168.2.89 "ls -la /mnt"

Adım 3: Büyük Veri Aktarımı (rsync) ve “Kullanıcılar Karışır mı?” Endişesi

Docker üzerinde docker inspect <konteyner_id> komutunu çalıştırarak Immich’in fotoğrafları ham olarak sakladığı ambarı bulduk: /mnt/.ix-apps/app_mounts/immich/library/

Transfere başlamadan önce akıllardaki en büyük soru şuydu: “Kürek kürek resimleri yeni sunucuya atınca kullanıcıların fotoğrafları birbirine karışacak mı?”

Kritik Bilgi: Immich, veri tabanında her kullanıcıya benzersiz bir UUID (harf ve sayılardan oluşan karmaşık kimlik) atar. Disk üzerinde de fotoğrafları library/UUID_kodu/ şeklinde klasörler halinde saklar. Yani fotoğraflar zaten diskin içinde birbirine tamamen izole odalardadır.

Ağ üzerinden canlı yayın yapar gibi dosyaları güvenle aktarmak, elektrik kesilse bile kaldığı yerden devam edebilmesini sağlamak için Linux’un en zeki aracı olan rsyncı çalıştırdık:

Bash

sudo rsync -avz --progress /mnt/.ix-apps/app_mounts/immich/library/ truenas_admin@192.168.2.89:/mnt/hdd_data/eski_immich_yedek/

  • -a parametresi sayesinde fotoğrafların çekilme ve oluşturulma tarihleri (metadata) hiç bozulmadan korundu.
  • -z ile veriler havada sıkıştırılarak ağ trafiği optimize edildi.

Sonuç ve Yeni Sunucuda Aktivasyon

Şu an 41 bin dosya yeni yatağına doğru güvenle akıyor. Transfer tamamlandığında yeni sunucudaki Immich üzerinde süreç şu iki adımla tamamlanacak:

  1. Yeni Immich’te, eski sunucudaki e-posta adresleriyle birebir aynı kullanıcı hesapları açılacak.
  2. Taşınan bu klasör, Yeni Immich’e “External Library” (Harici Kütüphane) olarak gösterilecek. Immich klasör yapısındaki UUID kodlarını tarayarak veri tabanındaki e-postalarla şak diye eşleştirecek ve herkes sadece kendi anılarını tertemiz bir şekilde görmeye devam edecek.

Sysadminlik; sabır, doğru log okuma ve protokollerin katı kurallarına saygı duyma sanatıdır. Bir sonraki teknik rehberimizde görüşmek üzere!

PowerShell: How to find whether the machine is waiting for Restart

The machine is waiting for restart, you can reach it simply by using the PowerShell command below.

Invoke-WmiMethod -Namespace "ROOTccmClientSDK" -Class CCM_ClientUtilities -Name DetermineIfRebootPending

One of my customers’ most inquiries was how to get the user machines to restart regularly.

First, we need to check whether the machine really needs restarts. If the machine wants to restart, we can produce various scenarios.
If the machine wants to restart, we can send the machine restart command.

Restart-Computer -ComputerName "ComputerName" -Force

Or it shows a warning to the user and the importance of restarting the machine can be explained. Such an interface can be improved either by HTML or again with PowerShell, allowing the user to confront it.

PowerShell ile makinenin Restart için bekleyip beklemediği nasıl bulunur?

Bir çok sistem yöneticisinin en büyük sorunlarından birisi de ağ üzerindeki makinelerin restart yapmasıdır. Peki bu bilgiye nasıl ulaşacağız ve bu bilgi bizim ne işimize yarayabilir?
Makinenin restart için beklediğini aşağıdaki PowerShell komutu ile basit bir şekilde öğrenebilirsiniz.

Continue reading “PowerShell ile makinenin Restart için bekleyip beklemediği nasıl bulunur?”

PowerShell: Change Port and URL quickly and accurately in multiple configuration files

PowerShell: Birden çok yapılandırma dosyasında Port ve URL’u hızlı ve doğru değiştirin

PowerShell_ISE

TR: Eğer bir çok uluslu bir şirkette altyapı yönetiyorsanız, bir küçük dosyayı tek tek düzenlemeniz gerekebilir. çünkü şirketin bir çok ülkeye hizmet veren bir web sayfası olacaktır. web sayfasının küçük ayar dosyası olacaktır. Bu dosyaları tek tek açıp düzenlemeye gerek yok. tüm ayarlamaları yapan bir script ile her ayarı hızlı ve doğru bir şekilde yapabilirsiniz.

EN: If you are managing the infrastructure in a multinational corporation, you may need to edit a small file one by one. because the company will have a web page that serves many countries. web page will be the small setting file. There is no need to open these files individually. With a script that makes all the adjustments you can make every setting quickly and accurately. Continue reading “PowerShell: Change Port and URL quickly and accurately in multiple configuration files”

If the folder exist, appy the .reg file

Klasör varsa, .reg dosyasını uygulayın.

regedit

Bazı uygulamaları makine kurduktan sonra ayarlarını her makinede tek tek yapmak gerekebilir. Yada aşağıdaki gibi bir script ile, eğer yüklediğimiz uygulamanın klasörü makinede var ise ayarları Regedit’e yükleyen daha hızlı bir yöntem seçebiliriz.

After installing some applications on the computers, you may need to adjust the settings of the applications one by one. Or, with a script such as the following, we can choose a faster method that installs the settings into Regedit if the machine has the application folder. Continue reading “If the folder exist, appy the .reg file”

PowerShell: Get information for an update installation when it is started, finished, and how long take

Microsoft’s updates never end. According to some system administrators, this is a headache. According to some system administrators, it is necessary for security. Although you are working with too many updates, in some cases you may need detailed information about the update installation. When did the update begin? When was the update installed? How long was the update set up?

PowerShell_ISE
In such situations grab the PowerShell help 🙂 Continue reading “PowerShell: Get information for an update installation when it is started, finished, and how long take”