Görselleri elle dönüştürmek, dört farklı boyut üretmek, WebP ve AVIF kopyalarını saklamak ve bunların hepsini yeni yüklenen her dosya için tekrarlamak bir noktadan sonra sürdürülemez hâle gelir. Bir katalogda on bin ürün varsa ve her ürün için dört boyut × üç format tutuyorsanız yüz yirmi bin dosyayla uğraşıyorsunuz demektir. Resim CDN'i bu problemi tersinden çözer: siz yalnızca orijinali saklarsınız, boyut ve format kararını istek anında CDN verir ve ürettiği kopyayı kendi kenar sunucularında önbelleğe alır.
Bu rehberde resim CDN'inin klasik CDN'den nerede ayrıldığını, URL parametreleriyle dönüşümün nasıl çalıştığını, hazır hizmetlerle kendi sunucunuzda çalıştıracağınız imgproxy gibi açık kaynak çözümler arasındaki farkı, önbellek ve maliyet dengesini, srcset ile birlikte nasıl kullanılacağını ve imzasız bir kurulumun neden ciddi bir güvenlik açığı olduğunu anlatacağım.
Resim CDN'i Klasik CDN'den Nerede Ayrılır#
Klasik bir CDN, origin sunucunuzdaki dosyayı olduğu gibi kopyalar ve ziyaretçiye coğrafi olarak yakın bir kenar sunucudan servis eder. Yani kapak.jpg dosyanız neyse, kenar sunucudan gelen de odur; CDN dosyanın içeriğine karışmaz, yalnızca mesafeyi kısaltır. Bir CDN katmanının bu temel işini ve ne zaman gerekli olduğunu CDN mi daha iyi hosting mi yazısında ele almıştım.
Resim CDN'i ise bunun üstüne bir dönüşüm katmanı ekler. Aynı kapak.jpg isteği geldiğinde şunlara bakar: istemci Accept başlığında hangi formatları destekliyor, URL'de hangi boyut isteniyor, hangi kalite ve kırpma parametreleri var. Sonra orijinali origin'den bir kez çeker, istenen varyantı üretir, kenar önbelleğine koyar ve servis eder. Aynı varyant bir daha istendiğinde üretim tekrarlanmaz.
| Özellik | Klasik CDN | Resim CDN |
|---|---|---|
| Dosyayı değiştirir mi | Hayır | Evet, istek anında |
| Kaç kopya saklarsınız | Ürettiğiniz kadar | Yalnızca orijinal |
| Format seçimi | Sizin işiniz | Accept başlığından otomatik |
| Boyutlandırma | Önceden üretilir | URL parametresiyle anında |
| Yeni format çıkarsa | Tüm arşivi dönüştürürsünüz | Ayar değişir, arşiv aynı kalır |
Son satır bu modelin en güçlü tarafıdır. AVIF yaygınlaştığında klasik kurulumda tüm arşivi yeniden dönüştürmeniz gerekir; resim CDN'inde tek bir ayar değişir ve ertesi gün destekleyen tarayıcılar AVIF almaya başlar. Orijinal dosyalarınıza hiç dokunulmaz.
URL Parametreleriyle Dönüşüm Nasıl Çalışır#
Resim CDN'lerinin ortak arayüzü URL'dir. Ne istediğinizi adres satırında tarif edersiniz; hizmetler arasında sözdizimi farklıdır ama mantık aynıdır:
# Genişliği 800 piksele indir, en-boy oranını koru
https://cdn.firmaniz.com/urunler/kapak.jpg?w=800
# 800x600 alanına kırparak sığdır, kaliteyi 75 yap
https://cdn.firmaniz.com/urunler/kapak.jpg?w=800&h=600&fit=cover&q=75
# Formatı istemciye göre otomatik seç (WebP/AVIF destekliyorsa onu ver)
https://cdn.firmaniz.com/urunler/kapak.jpg?w=800&format=auto
# 2x ekranlar için aynı görselin yüksek yoğunluklu hâli
https://cdn.firmaniz.com/urunler/kapak.jpg?w=1600&q=70
Buradaki fit parametresi sık karıştırılır ve iki yaygın davranışı vardır. cover (bazı hizmetlerde crop) istenen alanı tamamen doldurur ve taşan kısmı keser; ürün kartı ızgaralarında istediğiniz budur, çünkü tüm kartlar aynı yükseklikte olur. contain (ya da fit) ise görselin tamamını çerçeveye sığdırır ve boşluk bırakır; logo gibi kırpılmaması gereken görsellerde kullanılır.
q (kalite) parametresini her URL'de belirtmek yerine hizmetin varsayılanına bırakmak genellikle daha iyidir; çoğu resim CDN'i formatına göre farklı ve iyi ayarlanmış varsayılanlar kullanır. Kalite değerlerinin format bazında nasıl farklılaştığını AVIF nedir, WebP'den farkı ne yazısında ayrıntılandırdım — WebP'nin 80'i ile AVIF'in 80'i aynı şey değildir ve resim CDN'i bu eşlemeyi sizin yerinize yapar.
İki Model: Origin-Pull ve Yükleme Tabanlı#
Resim CDN'leri kaynağa nasıl ulaştıklarına göre ikiye ayrılır ve bu ayrım kurulum kararınızı doğrudan etkiler.
Origin-pull modelinde görseller sizin sunucunuzda kalır. CDN, ilk istekte origin'den orijinali çeker, dönüştürür, önbelleğe alır. Avantajı geçişin neredeyse sıfır maliyetli olmasıdır: mevcut dosya yapınıza hiç dokunmazsınız, yalnızca HTML'deki görsel adreslerini CDN alan adına çevirirsiniz. Dezavantajı, origin'inizin ayakta olması gerekmesidir — önbellekte olmayan bir varyant istendiğinde CDN size gelir.
Yükleme tabanlı modelde görselleri doğrudan hizmetin depolamasına yüklersiniz ve origin'iniz denklemden çıkar. Avantajı origin bağımsızlığı ve genellikle daha iyi dayanıklılıktır; dezavantajı ise yükleme akışınızı değiştirmeniz ve bir sağlayıcıya bağlanmanızdır. Görselleriniz artık sizin sunucunuzda değildir, dolayısıyla yedekleme sorumluluğu da yer değiştirir. Kendi kopyanızı tutmak istiyorsanız yedekleme planınızı buna göre kurun.
Pratikte çoğu site için origin-pull daha uygundur: mevcut kuruluma dokunmadan denersiniz, işe yaramazsa DNS ya da HTML değişikliğiyle geri dönersiniz. Kilitlenme riski düşüktür.
Hazır Hizmetler ve Cloudflare Tarafı#
Cloudflare kullanıyorsanız iki farklı ürünle karşılaşırsınız ve ikisi aynı şey değildir.
Polish, mevcut görsellerinizi kenar sunucuda yeniden sıkıştırır ve isteğe bağlı olarak WebP'ye çevirir. Boyutlandırma yapmaz; yani 2400 piksellik dosyanız 2400 piksel kalır, sadece daha iyi sıkıştırılır. Kurulumu tek anahtardır ve HTML'inizde hiçbir değişiklik gerektirmez. Mevcut görselleri elle optimize etmediyseniz kolay bir kazançtır.
Image Resizing / Images, asıl resim CDN'i davranışını sunar: URL parametreleriyle boyutlandırma, kırpma ve format seçimi. Bu, HTML'inizdeki görsel adreslerini değiştirmenizi gerektirir ve genellikle ücretli planlara bağlıdır.
Her iki durumda da ön koşul aynıdır: alan adınızın Cloudflare üzerinden proxy'lenmesi, yani turuncu bulutun açık olması. Yalnızca DNS olarak barındırıyorsanız trafik Cloudflare'dan geçmez ve bu ürünlerin hiçbiri devreye girmez. Bu ayrımı ve temel kurulumu Cloudflare DNS ve CDN rehberinde bulabilirsiniz.
Cloudflare dışında da çok sayıda hazır resim CDN'i vardır. Seçerken bakmanız gereken üç şey: fiyatlandırmanın neye göre yapıldığı (istek sayısı mı, üretilen benzersiz varyant sayısı mı, aktarılan bayt mı), imzalı URL desteği olup olmadığı ve kendi alan adınızı bağlayıp bağlayamayacağınız. Üçüncüsü özellikle önemlidir; görselleriniz cdn.firmaniz.com üzerinden gidiyorsa ileride sağlayıcı değiştirmek yalnızca bir DNS değişikliğidir.
Kendi Sunucunuzda: imgproxy#
Bir sağlayıcıya bağlanmak istemiyorsanız açık kaynak bir dönüşüm sunucusu çalıştırabilirsiniz. imgproxy bu iş için en yaygın kullanılan araçtır: tek bir ikili dosya, durumsuz (stateless) çalışır, orijinali HTTP ile ya da nesne depolamasından çeker, dönüştürür ve döner. Önbelleklemeyi kendisi yapmaz; onu önündeki Nginx ya da CDN katmanına bırakır.
Docker ile en hızlı başlangıç şöyledir:
docker run -d --name imgproxy --restart unless-stopped \
-p 127.0.0.1:8080:8080 \
-e IMGPROXY_KEY="$(openssl rand -hex 32)" \
-e IMGPROXY_SALT="$(openssl rand -hex 32)" \
-e IMGPROXY_ALLOWED_SOURCES="https://firmaniz.com/" \
-e IMGPROXY_MAX_SRC_RESOLUTION=50 \
-e IMGPROXY_ENFORCE_WEBP=true \
-e IMGPROXY_ENFORCE_AVIF=true \
darthsim/imgproxy:latest
Buradaki dört ortam değişkeni kritiktir. IMGPROXY_KEY ve IMGPROXY_SALT, URL imzalama için kullanılır — birazdan neden zorunlu olduklarına geleceğim. IMGPROXY_ALLOWED_SOURCES hangi origin'lerden görsel çekilebileceğini sınırlar. IMGPROXY_MAX_SRC_RESOLUTION ise megapiksel cinsinden bir üst sınır koyar ve devasa bir dosyanın belleği tüketmesini engeller.
Önüne bir Nginx koyup önbelleklemeyi orada yapmak, bu mimarinin standart hâlidir:
# Dönüştürülmüş varyantları diskte önbelleğe al
proxy_cache_path /var/cache/nginx/img levels=1:2 keys_zone=imgcache:50m
max_size=10g inactive=30d use_temp_path=off;
server {
listen 443 ssl;
server_name cdn.firmaniz.com;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_cache imgcache;
proxy_cache_valid 200 30d;
proxy_cache_valid 404 1m;
# Aynı URL için eş zamanlı istekleri tek üretime indir
proxy_cache_lock on;
proxy_cache_use_stale error timeout updating;
# Önbellek isabetini gözlemek için
add_header X-Cache-Status $upstream_cache_status;
expires 30d;
add_header Cache-Control "public, immutable";
}
}
proxy_cache_lock on; satırı gözden kaçırılmamalı: bir varyant ilk kez istendiğinde eş zamanlı yüz istek gelirse, bu satır olmadan yüz ayrı dönüşüm başlar ve sunucu kilitlenir. Nginx önbellekleme yönergelerinin genel mantığını Nginx FastCGI cache yapılandırması yazısında bulabilirsiniz; buradaki proxy_cache ailesi aynı mantıkla çalışır.
Kurulumu doğrulamak için önbellek durumunu izleyin:
# İlk istek MISS, ikinci istek HIT dönmeli
curl -sI "https://cdn.firmaniz.com/.../kapak.jpg" | grep -i x-cache-status
Güvenlik: İmzasız URL Neden Tehlikeli#
Bu bölüm, kendi dönüşüm sunucunuzu çalıştıracaksanız atlanmaması gereken kısımdır. İmzasız bir kurulumda URL'yi eline geçiren herkes istediği parametreyi verebilir. İki somut saldırı vardır.
Birincisi kaynak tüketimi. ?w=1, ?w=2, ?w=3 diye giden bir betik, her istekte önbellekte olmayan yeni bir varyant üretir. Her varyant bir dönüşüm işi demektir; birkaç bin istek CPU'yu doldurur, disk önbelleği şişer ve gerçek ziyaretçiler yanıt alamaz. Önbellek sizi korumaz, çünkü saldırgan bilerek hiç önbelleğe girmemiş kombinasyonlar üretir.
İkincisi SSRF. Dönüşüm sunucusu, kendisine verilen adresten görsel çeker. Kaynak adresi sınırlandırılmamışsa saldırgan http://127.0.0.1:8080/ ya da bir bulut sağlayıcının metadata adresi gibi iç ağ hedefleri verebilir ve sunucunuzun içeriden erişebildiği kaynakları dışarı sızdırabilir.
Her iki riskin de tek bir çözümü var: URL imzalama. imgproxy bunu IMGPROXY_KEY ve IMGPROXY_SALT ile yapar; uygulamanız her görsel adresini bir HMAC ile imzalar ve imzası geçersiz istekler reddedilir. Yani parametre kombinasyonlarını yalnızca sizin uygulamanız üretebilir. Buna ek olarak IMGPROXY_ALLOWED_SOURCES ile kaynak origin'leri açıkça sınırlayın ve IMGPROXY_MAX_SRC_RESOLUTION ile dosya boyutu tavanı koyun.
Hazır bir hizmet kullanıyorsanız aynı soruyu sorun: imzalı URL destekliyor mu, desteklemiyorsa hangi parametreler sınırlı? Sınırsız parametre kabul eden ve istek başına ücretlendiren bir hizmet, doğrudan bir fatura riski demektir.
srcset ile Birlikte Kullanmak#
Resim CDN'i tek başına doğru boyutu bilemez; hangi ziyaretçiye hangi genişliğin gideceğine yine tarayıcı karar verir. Bu yüzden ikisi birlikte çalışır: srcset içindeki her adayı CDN URL'i olarak yazarsınız ve önceden dosya üretmeden istediğiniz kadar basamak tanımlayabilirsiniz.
<img
src="https://cdn.firmaniz.com/urunler/kapak.jpg?w=800&format=auto"
srcset="https://cdn.firmaniz.com/urunler/kapak.jpg?w=400&format=auto 400w,
https://cdn.firmaniz.com/urunler/kapak.jpg?w=800&format=auto 800w,
https://cdn.firmaniz.com/urunler/kapak.jpg?w=1200&format=auto 1200w,
https://cdn.firmaniz.com/urunler/kapak.jpg?w=1600&format=auto 1600w"
sizes="(max-width: 768px) 100vw, 800px"
alt="Ürün kapak görseli"
width="1600" height="900"
loading="lazy" decoding="async">
Modelin güzelliği burada görünür: klasik kurulumda dört basamak eklemek dört yeni dosya üretmek demektir; burada yalnızca dört satır HTML'dir. format=auto sayesinde picture elementine ve ayrı AVIF/WebP kaynaklarına da gerek kalmaz — CDN Accept başlığına bakıp doğru formatı kendisi seçer ve Vary: Accept başlığını göndermek de onun sorumluluğudur.
sizes değerini yine de doğru yazmanız gerekir; CDN düzeninizi bilmez. Bu özniteliğin nasıl hesaplandığını responsive görseller: srcset ve sizes yazısında, ekranın altındaki görselleri geciktirme kurallarını ise lazy loading nasıl uygulanır rehberinde bulabilirsiniz.
Sık Yapılan Hatalar#
Sonsuz varyant üretimine izin vermek. İmzasız bir kurulumda ya da parametreleri sınırlamayan bir hizmette, üretilen benzersiz varyant sayısı kontrolden çıkar. srcset basamaklarınızı sabit bir listeye bağlayın (örneğin 400/800/1200/1600) ve her sayfada farklı genişlikler üretmeyin.
Önbellek başlıklarını CDN'e bırakmamak. Dönüştürülmüş görsel, içeriği değişmeyen türetilmiş bir varlıktır; uzun Cache-Control süresi ve immutable uygundur. Kısa bir TTL, her seferinde yeniden dönüşüm demektir ve modelin tüm avantajını yok eder.
Orijinali de CDN üzerinden servis etmek. Kaynak dosyanın kendisi genellikle çok büyüktür; kimsenin doğrudan orijinale erişememesi gerekir. Yalnızca dönüştürülmüş adresleri yayınlayın.
width ve height özniteliklerini atlamak. CDN boyutu istek anında ürettiği için HTML'de oranı bildirmezseniz görsel gelene kadar sayfa boş kalır ve sonra zıplar. Görsel gelmeden yer ayrılması için bu iki öznitelik zorunludur.
Maliyeti sadece bant genişliğiyle hesaplamak. Çoğu hizmet üretilen benzersiz varyant başına da ücretlendirir. Kaç ürün × kaç basamak × kaç format hesabını önceden yapın; toplam aktarımı kabaca kestirmek için bant genişliği hesaplayıcı aracımızı kullanabilirsiniz.
Origin'i tamamen ihmal etmek. Origin-pull modelinde origin'iniz hâlâ gereklidir; önbellekte olmayan her yeni varyant için size gelinir. Origin yavaşsa ilk isteklerde gecikme yaşanır.
Sıkça Sorulan Sorular#
Resim CDN'i klasik CDN'den farklı mı#
Evet, ikisi farklı işler yapar. Klasik CDN dosyanızı olduğu gibi kopyalar ve ziyaretçiye yakın bir kenar sunucudan servis eder; amaç mesafeyi kısaltmaktır. Resim CDN'i bunun üstüne bir dönüşüm katmanı ekler: aynı orijinalden istek anında farklı boyut ve formatlarda varyantlar üretir, bunları önbelleğe alır. Yani klasik CDN taşır, resim CDN'i hem üretir hem taşır.
Resim CDN'i kullanmak pahalı mı#
Fiyatlandırma modeline çok bağlıdır ve karşılaştırırken dikkatli olmak gerekir. Bazı hizmetler aktarılan bayta, bazıları istek sayısına, bazıları da üretilen benzersiz varyant sayısına göre ücretlendirir. Üçüncü modelde srcset basamaklarınızı sabit tutmak maliyeti öngörülebilir kılar. Kendi sunucunuzda imgproxy çalıştırmak yazılım açısından ücretsizdir, maliyeti CPU ve disk önbelleği olarak ödersiniz.
Kendi sunucumda mı çalıştırmalıyım yoksa hazır hizmet mi#
Trafiğiniz orta ölçekliyse ve sunucu yönetimine hâkimseniz imgproxy gibi bir çözüm hem maliyetli değildir hem de tam denetim verir; ancak imzalama, kaynak sınırlama ve önbellek katmanını doğru kurmak sizin sorumluluğunuzdadır. Küresel bir kitleye hizmet ediyorsanız ve kenar sunucu ağının coğrafi yaygınlığı önemliyse hazır bir hizmet daha iyi sonuç verir. Origin-pull modelini seçerseniz ikisi arasında geçiş yapmak da kolaydır.
Mevcut görsel URL'lerimi değiştirmem gerekir mi#
Kullandığınız ürüne bağlıdır. Cloudflare Polish gibi yalnızca yeniden sıkıştırma yapan çözümlerde HTML'e hiç dokunmazsınız; ayar açılır ve kenar sunucu görselleri optimize eder. Buna karşılık boyutlandırma yapan gerçek bir resim CDN'inde adresleri değiştirmeniz gerekir, çünkü istenen genişlik URL'de taşınır. Kendi alan adınızı (cdn.firmaniz.com) bağlarsanız bu değişikliği bir kez yaparsınız ve ileride sağlayıcı değiştirmek yalnızca DNS işine döner.
Resim CDN'i SEO'yu etkiler mi#
Doğru kurulduğunda olumlu etkiler, çünkü sayfa ağırlığını ve yükleme süresini düşürür. Dikkat etmeniz gereken üç nokta var: görsellerin arama motoru tarayıcıları tarafından erişilebilir olması (imzalı URL'ler HTML'de yayınlandığı için sorun çıkarmaz), alt metinlerini eksiksiz yazmak ve görsel adreslerinin kararlı kalması. Sürekli değişen URL'ler görsel indekslemesini sıfırlar; basamak listenizi sabit tutun.
İmzalı URL kullanmak zorunda mıyım#
Kendi dönüşüm sunucunuzu çalıştırıyorsanız evet, bunu isteğe bağlı bir güvenlik önlemi olarak görmeyin. İmzasız bir kurulumda herkes rastgele parametrelerle sonsuz sayıda yeni varyant ürettirebilir; bu hem CPU'yu tüketir hem de disk önbelleğini şişirir. Ayrıca kaynak adresi sınırlanmamışsa iç ağ hedeflerine istek yaptırma riski doğar. İmzalama, kaynak allowlist'i ve çözünürlük tavanı üçlüsü birlikte kurulmalıdır.
Kapanış#
Resim CDN'i, görsel optimizasyonunu tek seferlik bir proje olmaktan çıkarıp altyapının kalıcı bir parçasına dönüştürür: siz orijinali saklarsınız, boyut ve format kararı istek anında verilir, yeni bir format çıktığında arşivinize hiç dokunmazsınız. Aklınızda kalması gereken dört alışkanlık şunlar: srcset basamaklarınızı sabit bir listeye bağlayın ki varyant sayısı kontrolden çıkmasın; kendi sunucunuzda çalıştırıyorsanız imzalama, kaynak sınırlama ve çözünürlük tavanını ilk günden kurun; dönüştürülmüş varlıklara uzun önbellek süresi verin; ve HTML'de width ile height özniteliklerini asla atlamayın.
Origin-pull modelinde origin'inizin hızlı ve kararlı olması hâlâ önemlidir; bu zemini sağlayan web hosting ve e-ticaret hosting paketlerimiz görsel yoğun kataloglar için uygun bir başlangıç sunar. Kendi dönüşüm sunucunuzu kurmak isterseniz Docker çalıştırabileceğiniz tam root erişimli VDS paketlerimize bakabilir, kurulumu ve önbellek katmanını bize bırakmak isterseniz sunucu yönetimi hizmetimizden yararlanabilirsiniz.