Google Fotoğraflar’ın ücretsiz depolama limitleri değiştiğinden beri, tüm dijital anılarımı kendi kontrolümde, kendi sunucumda barındırma fikri kafamda dönüp duruyordu. Geçen ay sonunda, yaklaşık 400 GB’lık fotoğraf ve video arşivimi Google’dan tamamen çekerek, açık kaynaklı Immich projesi ile kendi VPS’ime taşıdım. Bu süreç, sadece verilerimi taşımakla kalmadı, aynı zamanda veri egemenliği ve uzun vadeli maliyetler konusunda da önemli dersler çıkarmamı sağladı.
Bu yazıda, Google Fotoğraflar’ı neden bıraktığımı, Immich’i neden seçtiğimi, kurulum ve veri taşıma adımlarını, karşılaştığım teknik zorlukları ve kendi fotoğraf sunucumu ayakta tutmak için uyguladığım bakım ve güvenlik stratejilerini detaylıca anlatacağım.
Neden Google Fotoğraflar’ı Bıraktım? Veri Egemenliği ve Maliyet
Yıllarca Google Fotoğraflar’ın rahatlığına alıştık. Telefonumdan çektiğim her şey otomatik yedekleniyor, aradığım her şeyi kolayca buluyordum. Ancak 2021’de sınırsız depolamanın sona ermesiyle birlikte, bu rahatlığın bir bedeli olacağını anladım. Benim için dönüm noktası, toplam 400 GB’a yakın fotoğraf ve video verimin olması ve Google’ın sunduğu 100 GB’lık ücretsiz kotayı aşmam oldu.
Yıllık 2 TB’lık depolama için ödemem gereken yaklaşık 100 USD tutarını görünce, bu maliyetin uzun vadede kendi sunucumda bir disk almaktan daha pahalıya geleceğini hesapladım. Üstelik, verilerimin Google’ın AI algoritmaları tarafından nasıl işlendiği ve mahremiyetimin ne kadar korunduğu konuları da kafamı kurcalıyordu. Bir üretim ERP’sinde çalışırken benzer bir veri egemenliği tartışması yaşamıştık; orada da kritik şirket verilerini bulutta tutmanın getirdiği riskler ve maliyetler bizi kendi altyapımıza yatırım yapmaya itmişti. Benim kişisel verilerim de benim için en az o kadar kritikti.
Immich Nedir ve Neden Immich’i Seçtim?
Google Fotoğraflar’a alternatif arayışım, beni bir dizi açık kaynaklı çözüme yönlendirdi. PhotoPrism, Nextcloud Photos gibi seçenekleri inceledim, ancak Immich, hem modern arayüzü hem de mobil uygulama desteğiyle beklentilerimi en çok karşılayan proje oldu. Immich, kendi kendine barındırılan bir fotoğraf ve video yedekleme çözümü sunuyor; AI destekli obje ve yüz tanıma, otomatik yedekleme, çok kullanıcılı destek gibi özellikleriyle dikkat çekiyor.
Immich’i tercih etmemdeki temel nedenler şunlardı:
- Mobil Uygulama: Hem Android hem de iOS için native uygulamaları sayesinde telefonumdan otomatik yedekleme yapabiliyorum. Kullanıcı deneyimi, Google Fotoğraflar’a oldukça benziyor.
- Aktif Geliştirme: Projenin GitHub deposu sürekli güncelleniyor, yeni özellikler hızla ekleniyor ve topluluk oldukça aktif. Bu, gelecekteki destek ve geliştirmeler için bana güven verdi.
- Microservice Mimarisi: Arka planda PostgreSQL, Redis ve birden fazla Immich servisi Docker konteynerları aracılığıyla çalışıyor. Bu yapı, performans ve ölçeklenebilirlik açısından bana tanıdık geldi; kurumsal yazılım mimarilerinde de benzer yaklaşımlar kullandığımız için yönetimi daha kolay olacaktı.
- AI Özellikleri: Kendi sunucumda çalışan AI algoritmaları sayesinde fotoğraflarımda obje ve yüz tanıma yapabiliyorum. Bu, verilerimi üçüncü taraf bir hizmete göndermeden akıllı arama yapabilmemi sağlıyor.
Diğer çözümler ya mobil uygulama konusunda yetersiz kalıyor ya da arayüzleri çok eski görünüyordu. Immich, modern bir deneyimi kendi kontrolümde sunma vaadiyle öne çıktı.
Immich Kurulum Süreci: Adım Adım Docker Compose ile
Immich’i kendi VPS’ime kurmak için Docker Compose kullandım. Benim için bare-metal sunucuda Docker konteynerları çalıştırmak, hem esneklik hem de kaynak yönetimi açısından her zaman en sevdiğim hibrit dağıtım yöntemidir. Kurulum öncesinde, 4GB RAM, 2vCPU’lu bir Ubuntu 22.04 LTS VPS’im hazırdı. Bu VPS üzerinde Docker ve Docker Compose kurulu durumdaydı.
Kurulum adımları genel olarak şöyle ilerledi:
-
Gereksinimler:
- Bir Linux sunucu (Ubuntu önerilir)
- Docker ve Docker Compose
- Yeterli depolama alanı (benim durumumda 2 TB NVMe disk)
- Nginx (reverse proxy ve SSL için)
- Bir alan adı (örneğin
foto.benimsitem.com)
-
Immich Proje Dosyalarını Çekme: Immich’in resmi GitHub deposundan
docker-compose.ymldosyasını indirdim. Bu dosya, tüm Immich servislerini (server, microservices, web, machine learning, PostgreSQL, Redis) tanımlıyor.mkdir -p /opt/immich && cd /opt/immich wget -O docker-compose.yml https://github.com/immich-app/immich/releases/latest/download/docker-compose.yml wget -O .env https://github.com/immich-app/immich/releases/latest/download/.env -
Ortam Değişkenlerini Ayarlama (.env):
.envdosyasını düzenleyerek kendi gereksinimlerime göre ayarlamalar yaptım. ÖzellikleDB_PASSWORD,UPLOAD_LOCATION(fotoğrafların depolanacağı dizin) veTZ(saat dilimi) gibi değişkenler önemliydi. Kendi sunucumda fotoğraflar için/mnt/data/immich_uploadsdizinini kullandım.# Örnek .env dosyası içeriği DB_PASSWORD=cok_guclu_sifre UPLOAD_LOCATION=/mnt/data/immich_uploads TZ=Europe/Istanbul # ... diğer Immich ayarları -
Konteynerları Başlatma: Tüm ayarları yaptıktan sonra, Immich servislerini tek bir komutla başlattım.
docker compose up -dBu komut, tüm servisleri arka planda başlattı ve konteyner imajlarını indirdi. İlk başlatma biraz zaman alabilir, çünkü birden fazla imajın indirilmesi ve PostgreSQL veritabanının ilk kurulumu yapılıyor.
docker compose logs -fkomutuyla servislerin durumunu takip ettim.
Immich servislerinin mimarisi oldukça modüler. Aşağıdaki Mermaid diyagramı, ana bileşenlerin birbirleriyle nasıl etkileşime girdiğini gösteriyor:
graph TD; A["Kullanıcı (Web/Mobil Uygulama)"] --> B["Nginx (Reverse Proxy)"]; B --> C["Immich Web"]; B --> D["Immich Server (API)"]; D --> E["Immich Microservices"]; D --> F["PostgreSQL"]; E --> F; E --> G["Redis"]; E --> H["Immich Machine Learning"]; H --> F; H --> G; F --> I["Depolama (immich_uploads)"]; E --> I;
Bu yapı, her bir bileşenin kendi sorumluluğunu yerine getirmesini sağlıyor ve bir parçanın çökmesi durumunda sistemin genelini etkilememesine yardımcı oluyor.
Google Takeout Verilerini Immich’e Aktarma ve Karşılaşılan Zorluklar
Immich kurulumu tamamlandıktan sonra, en kritik adım Google Fotoğraflar’dan indirdiğim verileri Immich’e aktarmaktı. Google Takeout ile tüm arşivimi ZIP dosyaları halinde indirmiştim. Ancak bu verilerin Immich’e düzgün bir şekilde aktarılması, beklediğimden daha karmaşık bir süreçti.
Google Takeout, her fotoğraf veya video için ayrı bir JSON dosyası (.json) oluşturarak metadata bilgilerini (çekim tarihi, konum vb.) saklıyor. Immich’in kendi içe aktarma aracı bu JSON dosyalarını okuyabiliyor ancak, Takeout’un klasör yapısı ve bazen eksik veya yanlış metadata bilgileri sorunlara yol açabiliyor.
İçe aktarım için immich-go adında bir CLI aracı kullandım. Bu araç, Google Takeout verilerini Immich’e aktarmak için özel olarak tasarlanmış.
-
Google Takeout Verilerini Hazırlama: Tüm ZIP dosyalarını açtım ve
immich-goaracının beklediği gibi tek bir kök dizin altına yerleştirdim. Örneğin:/mnt/data/google_takeout_data. -
immich-goAracını Kurma: Go yüklü bir sistemde (ben kendi laptopumda kurdum) aşağıdaki komutla aracı kurdum:go install github.com/alextran1502/immich-go@latest -
Verileri Immich’e Aktarma: Immich sunucumun adresini ve API anahtarını belirterek
immich-goile aktarımı başlattım.immich-go upload --server https://foto.benimsitem.com --api-key <IMMICH_API_KEY> --recursive /mnt/data/google_takeout_dataBurada karşılaştığım en büyük zorluklardan biri, bazı fotoğrafların metadata’sının Takeout JSON’larında bozuk çıkmasıydı. Özellikle çok eski fotoğraflarda veya farklı cihazlardan yüklenen videolarda EXIF bilgileri eksik olabiliyordu. Bu durum, Immich’in bu dosyaları doğru zaman damgasıyla indekslemesini engelledi. Bazı dosyalar
2000-01-01gibi varsayılan tarihlerle ortaya çıktı. Bu, üretim ERP’sinde IFRS entegrasyonu yaparken karşılaştığımız tarih formatı ve veri bütünlüğü sorunlarını hatırlattı; veri kalitesi her zaman en büyük problem kaynağıdır.Bu tür sorunları tespit etmek için, aktarım sonrası Immich arayüzünde “Son Yüklenenler” kısmını dikkatlice inceledim ve tarihleri garip görünen dosyaları manuel olarak bulup düzelttim. Bazen de
exiftoolgibi araçlarla JSON’daki bilgileri kullanarak fotoğrafların EXIF verilerini güncelledim.
Immich Altyapısını Ayakta Tutmak: Bakım, Güvenlik ve Performans
Kendi fotoğraf sunucumu kurmak, sadece kurulumla biten bir iş değil. Sürekli bakım, güvenlik güncellemeleri ve performans optimizasyonu gerektiriyor. Bu, benim 20 yıllık sistem yönetimi deneyimimde edindiğim “kurulum bitmez, operasyon başlar” ilkesinin bir başka örneği oldu.
Bakım ve Güncellemeler
Immich aktif olarak geliştirildiği için düzenli olarak güncellemeleri takip etmek önemli. Genellikle haftalık olarak docker compose pull && docker compose up -d komutlarını çalıştırarak konteynerları en son versiyonlara güncelliyorum. Bu, yeni özelliklerin yanı sıra kritik güvenlik yamalarını da almamı sağlıyor.
Güvenlik
Immich sunucumun güvenliği için birkaç katmanlı bir yaklaşım izledim:
-
Nginx Reverse Proxy ve SSL: Immich’e doğrudan erişim yerine, tüm trafiği Nginx üzerinden yönlendirdim. Let’s Encrypt ile ücretsiz SSL sertifikası kullanarak tüm trafiğin şifreli olmasını sağladım. Bu,
L7 load balancingsenaryolarında da sıklıkla kullandığım bir yaklaşımdır.# /etc/nginx/sites-available/immich.conf server { listen 80; server_name foto.benimsitem.com; return 301 https://$host$request_uri; } server { listen 443 ssl http2; server_name foto.benimsitem.com; ssl_certificate /etc/letsencrypt/live/foto.benimsitem.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/foto.benimsitem.com/privkey.pem; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384"; ssl_prefer_server_ciphers on; location / { proxy_pass http://immich_web:3000; # Immich web container adı ve portu proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; # Büyük dosya yüklemeleri için önemli client_max_body_size 0; # Sınırsız dosya boyutu } location /api { proxy_pass http://immich_server:3001; # Immich API container adı ve portu proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_buffering off; client_max_body_size 0; } } -
Fail2ban: Sunucuya yapılan başarısız giriş denemelerini engellemek için
fail2bankurdum. Nginx loglarını izleyerek brute-force saldırılarını otomatik olarak engelliyor. Bu, her zaman ilk yaptığım güvenlik önlemlerinden biridir. -
Firewall (UFW): Sadece gerekli portları (80, 443) açarak sunucunun diğer portlarının dışarıdan erişilemez olmasını sağladım. Immich’in konteynerları arasındaki iletişimi de Docker’ın kendi network’ü üzerinden izole ettim.
-
Sistem Güvenliği: Linux kernel modüllerini izliyorum (
auditdile) ve bilinen CVE’leri takip ediyorum. Örneğin, daha öncealgif_aeadmodülündeki bir güvenlik açığı için kernel modülünü blacklist’e almıştım. Bu tür önlemler, sunucunun genel güvenliğini artırıyor.
Performans Optimizasyonu
Immich’in hızlı ve sorunsuz çalışması için bazı performans ayarları yaptım:
-
PostgreSQL Tuning: Immich’in kalbi PostgreSQL olduğu için veritabanı ayarlarını optimize ettim. Özellikle
shared_buffers,work_memvemax_connectionsparametrelerini sunucumun RAM’ine ve kullanım modelime göre ayarladım. WAL bloat sorununu önlemek içincheckpoint_completion_targetvemax_wal_sizeayarlarını da optimize ettim.-- postgresql.conf'ta yapılan bazı ayarlamalar shared_buffers = 1GB # Toplam RAM'in %25'i civarı work_mem = 64MB # Sorgu başına hafıza maintenance_work_mem = 256MB # VACUUM gibi işlemler için max_connections = 100 # Uygulamanın bağlantı ihtiyacına göre wal_level = replica max_wal_size = 4GB # WAL dosyalarının maksimum boyutu checkpoint_completion_target = 0.9 # Checkpoint süresini uzatmak için -
Redis Eviction Policy: Redis, Immich tarafından önbellekleme için kullanılıyor. Bellek dolduğunda hangi verinin atılacağını belirleyen
maxmemory-policyayarınıallkeys-lruolarak belirledim. Bu sayede en az kullanılan anahtarlar atılarak önemli verilerin bellekte kalması sağlandı. -
Konteyner Kaynak Limitleri: Docker Compose içinde
cgroupayarlarını kullanarak Immich konteynerlarının RAM ve CPU kullanımını sınırladım. Özellikleimmich-machine-learningservisi yüksek CPU ve RAM tüketebildiği için bu kritikti.memory.highyumuşak limiti, bir servisin belleği aşırı kullanmasını engellerken, anlık yükselişlere de tolerans gösteriyor.# docker-compose.yml içinde immich-machine-learning servisi için örnek immich-machine-learning: image: ghcr.io/immich-app/immich-machine-learning:latest restart: always environment: # ... deploy: resources: limits: cpus: '1.0' memory: 2G reservations: cpus: '0.5' memory: 1G -
İzleme (Monitoring): Prometheus ve Grafana kullanarak sunucumun ve Immich servislerinin performansını sürekli izliyorum. Disk doluluğu (daha önce “docker disk yangını” yaşadığım için bu konuda hassasım), CPU, RAM ve network trafiği gibi metrikleri takip ediyorum. Bir alarm eşiği aşıldığında bana bildirim düşüyor.
Yedekleme Stratejisi
Kendi fotoğraf sunucumdaki en önemli konu yedekleme. Tüm anılarımın kaybolması felaket olurdu. Bu yüzden Immich verilerini düzenli olarak yedekliyorum:
- PostgreSQL Veritabanı Yedeklemesi: Her gece
pg_dumpkullanarak veritabanının yedeğini alıp ayrı bir depolama alanına (farklı bir sunucudaki bir SMB paylaşımı) kopyalıyorum. - Fotoğraf ve Video Dosyaları:
UPLOAD_LOCATIONolarak belirlediğim dizini (yani/mnt/data/immich_uploads)rsyncile her gece senkronize ederek ayrı bir depolama birimine yedekliyorum.
Bu iki yedekleme stratejisi, herhangi bir felaket durumunda Immich kurulumumu tamamen geri yükleyebilmemi sağlıyor.
Kendi Sunucumda Fotoğraf Yönetiminin Trade-off’ları ve Gelecek Planları
Google Fotoğraflar’dan Immich’e geçiş, benim için teknik bir meydan okuma olmanın ötesinde, dijital varlıklarım üzerindeki kontrolümü geri kazanma anlamına geliyordu. Ancak her teknolojik kararda olduğu gibi, bu yaklaşımın da kendine göre avantajları ve dezavantajları var.
Avantajlar:
- Tam Kontrol ve Mahremiyet: Verilerimin nerede depolandığını, kimlerin erişebildiğini ve hangi algoritmalarla işlendiğini tam olarak biliyorum. Üçüncü taraf bir şirketin gizlilik politikalarına bağımlı değilim.
- Maliyet Etkinliği: İlk kurulum maliyeti olsa da (VPS, disk), uzun vadede yıllık abonelik ücretlerinden daha uygun. Özellikle yüksek depolama ihtiyacı olanlar için bu fark daha da belirginleşiyor.
- Esneklik: Kendi sunucumda olduğu için Immich’i kendi ihtiyaçlarıma göre özelleştirebilir, farklı servislerle entegre edebilirim (örneğin, kendi yan ürünümdeki bir yapay zeka modelini fotoğraflarımı etiketlemek için kullanabilirim).
- Öğrenme Fırsatı: Bu süreç, Docker, PostgreSQL tuning, Nginx yapılandırması ve Linux sistem yönetimi konularında pratik deneyimimi pekiştirmemi sağladı.
Dezavantajlar:
- Bakım Yükü: Sistem güncellemeleri, yedekleme, güvenlik yamaları ve olası sorun giderme işlemleri tamamen benim sorumluluğumda. Bu, zaman ve teknik bilgi gerektiriyor.
- İlk Kurulum Karmaşası: Google Fotoğraflar’ın “tak ve çalıştır” kolaylığından sonra, Immich’in kurulumu ve veri aktarımı daha fazla teknik bilgi ve sabır gerektirdi.
- İnternet Bağlantısı: Ev internetimin upload hızı sınırlı olduğu için, ilk senkronizasyon ve büyük video dosyalarının yüklenmesi günler sürdü. Yüksek çözünürlüklü fotoğraflar ve 4K videolar için iyi bir upload hızı kritik.
- Yedekleme Sorumluluğu: Veri kaybını önlemek için sağlam bir yedekleme stratejisi oluşturmak ve düzenli olarak kontrol etmek gerekiyor. Bu, bulut servislerinin otomatik yedekleme kolaylığına alışkın olanlar için ek bir sorumluluk.
Gelecek Planları
Immich ile yolculuğum daha yeni başlıyor. Gelecekte, Immich’in AI yeteneklerini daha da geliştirmeyi hedefliyorum. Özellikle kendi geliştirdiğim bazı AI modellerini (prompt engineering ve RAG desenlerini kullanarak) Immich’e entegre ederek daha akıllı arama ve otomatik etiketleme özellikleri eklemeyi düşünüyorum. Ayrıca, farklı cihazlardan (aksiyon kameraları, dronelar) gelen fotoğrafları otomatik olarak Immich’e senkronize edecek betikler yazmak da planlarım arasında.
Bu geçiş, “monolith vs microservice” tartışmasındaki gibi, bir sistemin tüm kontrolünü elinizde tutmanın getirdiği faydaları ve sorumlulukları bir kez daha hatırlattı. Benim tercihim, kişisel verilerim söz konusu olduğunda, her zaman kontrolü ele almak yönünde oldu.
Immich deneyimimden oldukça memnunum. Kendi verilerimi kendi sunucumda barındırmak, bana hem huzur hem de teknolojik bir tatmin sağladı. Eğer siz de dijital anılarınızın kontrolünü ele almak istiyorsanız, Immich kesinlikle değerlendirmeniz gereken bir proje. Bir sonraki yazıda, bu Immich kurulumunu sıfır güven (Zero-Trust Network Access - ZTNA) mimarisiyle nasıl entegre ettiğimi anlatacağım.