Cloudflare Pages ile Statik Site Yayınlama Rehberi
Statik site barındırma dünyasında Cloudflare Pages son birkaç yılda ciddi bir oyun değiştirici oldu. Daha önce Netlify veya Vercel kullanıyorduysanız, Cloudflare Pages’in ne kadar benzer ama bir o kadar da farklı çalıştığını göreceksiniz. Bu yazıda Cloudflare Pages’i sıfırdan kurup, DNS yönetimiyle entegre ederek production ortamına hazır hale getireceğiz.
Cloudflare Pages Nedir ve Neden Kullanmalısınız?
Cloudflare Pages, statik site ve JAMstack uygulamalarını deploy etmek için tasarlanmış bir platform. Git tabanlı workflow ile çalışıyor, yani her push işleminizde otomatik build ve deploy gerçekleşiyor. Ücretsiz katmanında bile sınırsız bant genişliği sunuyor, bu da onu özellikle başlangıç projeleri için çok cazip yapıyor.
Ama asıl güç, Cloudflare’in kendi global CDN ağıyla entegre çalışmasından geliyor. Siteniz 200’den fazla PoP (Point of Presence) üzerinden servis ediliyor ve DNS yönetimini de aynı panelden yapabiliyorsunuz. Bu entegrasyon, başka platformlarda genellikle ekstra konfigürasyon gerektiren şeyleri burada çok daha basit hale getiriyor.
Ön Hazırlıklar
Başlamadan önce şunların hazır olması gerekiyor:
- Cloudflare hesabı (ücretsiz plan yeterli)
- GitHub veya GitLab hesabı
- Basit bir statik site veya framework projesi
- Cloudflare’e taşınmış veya yeni eklenmiş bir domain
Domain konusunda önemli bir not: Cloudflare Pages’in custom domain özelliğini tam anlamıyla kullanabilmek için domaininizin nameserver’larının Cloudflare’e yönlendirilmiş olması gerekiyor. Bu olmadan da *.pages.dev subdomain üzerinden çalışabilirsiniz ama production için custom domain şart.
Projeyi Hazırlama
Önce basit bir test projesi oluşturalım. Bu örnekte Hugo kullanacağız ama aynı adımlar Next.js, Gatsby, Jekyll veya plain HTML için de geçerli.
# Hugo kurulumu (Ubuntu/Debian)
sudo apt-get install hugo
# Yeni site oluştur
hugo new site my-cloudflare-site
cd my-cloudflare-site
# Tema ekle
git init
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke
# config.toml'a tema ekle
echo 'theme = "ananke"' >> config.toml
# Test içerik oluştur
hugo new posts/ilk-yazi.md
Şimdi bu projeyi GitHub’a push edelim:
# GitHub'da repo oluşturduktan sonra
git add .
git commit -m "Initial commit"
git remote add origin https://github.com/kullanici/my-cloudflare-site.git
git branch -M main
git push -u origin main
Build komutunu ve output dizinini bilmek önemli çünkü Cloudflare Pages kurulumunda bunları gireceğiz:
- Hugo için build komutu:
hugo - Hugo için output dizini:
public - Next.js için build komutu:
npm run build - Next.js için output dizini:
out(static export kullanıyorsanız) - Jekyll için build komutu:
jekyll build - Jekyll için output dizini:
_site
Cloudflare Pages Projesi Oluşturma
Cloudflare Dashboard’a giriş yaptıktan sonra sol menüden “Workers & Pages” bölümüne gidin. “Create Application” butonuna tıklayın ve “Pages” sekmesini seçin.
Git’e Bağlanma
“Connect to Git” butonuyla GitHub veya GitLab hesabınızı bağlayın. OAuth akışı sizi ilgili platforma yönlendirecek. Burada dikkat etmeniz gereken nokta: Cloudflare’e tüm repolarınıza mı yoksa sadece belirli repolara mı erişim izni vereceğiniz. Production ortamı için sadece ilgili repoya erişim vermek daha güvenli bir pratik.
Build Ayarları
Repo seçiminden sonra build ayarları ekranı gelecek:
# Hugo için örnek ayarlar
Production branch: main
Build command: hugo --minify
Build output directory: /public
# Environment variable eklemek gerekirse
HUGO_VERSION: 0.110.0
Hugo versiyonunu environment variable olarak belirtmek çok önemli. Belirtmezseniz Cloudflare eski bir Hugo versiyonu kullanabilir ve temanız düzgün render olmayabilir. Bunu öğrenmek için biraz zaman kaybetmiştim, şimdiden söylüyorum.
Wrangler CLI ile Komut Satırından Yönetim
Cloudflare Pages’i sadece web arayüzünden değil, Wrangler CLI üzerinden de yönetebilirsiniz. Bu özellikle CI/CD pipeline’larında veya script bazlı deployment’larda işe yarıyor.
# Wrangler kurulumu
npm install -g wrangler
# Cloudflare hesabına giriş
wrangler login
# Mevcut Pages projelerini listele
wrangler pages project list
# Manuel deployment (build edilmiş dizinden)
wrangler pages deploy ./public --project-name=my-cloudflare-site
# Belirli bir branch'e deploy
wrangler pages deploy ./public --project-name=my-cloudflare-site --branch=staging
Wrangler CLI özellikle preview deployment’lar için çok kullanışlı. Bir feature branch’i test etmek istediğinizde local build alıp doğrudan Cloudflare’e push edebilirsiniz.
Custom Domain Bağlama ve DNS Yapılandırması
Bu kısım konumuzun özü. Cloudflare Pages projenizi oluşturduktan sonra otomatik olarak proje-adi.pages.dev adresinden erişilebilir oluyor. Ama production için kendi domaininizi kullanacaksınız.
Cloudflare Dashboard’dan Domain Ekleme
Pages projenizin ayarlarında “Custom Domains” sekmesine gidin ve “Set up a custom domain” butonuna tıklayın. Domain adresinizi girin, örneğin blog.ornek.com.
Eğer domaininiz zaten Cloudflare’deyse, DNS kaydı otomatik olarak oluşturulacak. Değilse manuel eklemeniz gerekecek.
DNS Kayıtlarını Manuel Yapılandırma
Cloudflare DNS panelinden aşağıdaki kayıtları ekleyin:
# Root domain için (ornek.com)
Type: CNAME
Name: @
Target: proje-adi.pages.dev
Proxy status: Proxied (turuncu bulut)
# Subdomain için (www.ornek.com)
Type: CNAME
Name: www
Target: proje-adi.pages.dev
Proxy status: Proxied (turuncu bulut)
Burada dikkat etmeniz gereken nokta: bazı DNS sağlayıcıları root domain (@) için CNAME kaydına izin vermiyor çünkü RFC standartlarına aykırı. Ama Cloudflare’in “CNAME Flattening” özelliği sayesinde bu sorun yok. Cloudflare, root domain için CNAME’i otomatik olarak A kaydına dönüştürüyor.
API ile DNS Kaydı Ekleme
Birden fazla domain yönetiyorsanız Cloudflare API üzerinden otomatize edebilirsiniz:
# Zone ID'yi öğren
curl -X GET "https://api.cloudflare.com/client/v4/zones?name=ornek.com"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
# DNS kaydı oluştur
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/dns_records"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
--data '{
"type": "CNAME",
"name": "blog",
"content": "proje-adi.pages.dev",
"ttl": 1,
"proxied": true
}'
TTL değeri 1 olarak ayarlandığında Cloudflare otomatik TTL kullanıyor. Proxied kayıtlar için bu zaten geçerli olan değer.
SSL/TLS Yapılandırması
Cloudflare Pages custom domain eklediğinizde SSL sertifikasını otomatik olarak sağlıyor. Ama bazı ayarları gözden geçirmek gerekiyor.
Cloudflare Dashboard’da domaininizin “SSL/TLS” bölümüne gidin:
- Encryption Mode: Full (Strict) seçin. Bu seçenek hem ziyaretçi ile Cloudflare arasındaki hem de Cloudflare ile origin arasındaki bağlantıyı şifreler. Pages kullanırken origin zaten Cloudflare’in kendi altyapısı olduğu için bu ideal seçenek.
- Always Use HTTPS: Açık olmalı
- Minimum TLS Version: TLS 1.2 veya üzeri
- Automatic HTTPS Rewrites: Açık olmalı, mixed content sorunlarını otomatik çözüyor
Preview Deployment’ları Yönetme
Cloudflare Pages’in güzel özelliklerinden biri her branch push’unda otomatik preview URL’i oluşturması. main branch dışındaki her push için branch-adi.proje-adi.pages.dev formatında bir URL oluşturuluyor.
Bu özelliği aktif olarak kullanıyorsanız birkaç şeyi ayarlamanız gerekebilir:
# .cfpages.yml oluştur (opsiyonel, proje konfigürasyonu için)
# Bu dosyayı repo root'una ekleyin
# Aşağıdaki wrangler.toml formatı da kullanılabilir
name = "my-cloudflare-site"
pages_build_output_dir = "./public"
[build]
command = "hugo --minify"
[build.environment]
HUGO_VERSION = "0.110.0"
NODE_VERSION = "18"
Preview deployment’ları için access control eklemek isteyebilirsiniz. Cloudflare Access ile preview URL’lerine şirket içi authentication koyabilirsiniz. Bu özellikle staging ortamları için çok işe yarıyor.
Redirect ve Header Yönetimi
Statik sitede redirect ve custom header yönetimi için iki yol var. Birincisi _redirects dosyası, ikincisi _headers dosyası. Bunları build output dizinine koymanız yeterli.
# public/_redirects veya static/_redirects (Hugo için)
# Eski URL'leri yeni URL'lere yönlendir
/eski-sayfa /yeni-sayfa 301
/blog/2022/* /arsiv/:splat 301
# Query parametreli redirect
/ara?q=:query /search?term=:query 301
# External redirect
/github https://github.com/kullanici 302
# 404 sayfası
/* /404.html 404
Custom header’lar için:
# public/_headers veya static/_headers
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
/static/*
Cache-Control: public, max-age=31536000, immutable
/*.html
Cache-Control: public, max-age=0, must-revalidate
Bu header yapılandırması özellikle security score’unuzu yükseltmek için önemli. securityheaders.com gibi araçlarla sitenizi test edebilirsiniz.
Gerçek Dünya Senaryosu: Çoklu Ortam Yönetimi
Production ortamında genellikle şu yapıyla çalışılır:
mainbranch ->ornek.com(production)stagingbranch ->staging.ornek.com(staging)devbranch -> otomatik preview URL (development)
Bu yapıyı kurmak için:
Staging subdomain için DNS kaydı:
# Cloudflare DNS panelinde
Type: CNAME
Name: staging
Target: staging.proje-adi.pages.dev
Proxy status: Proxied
Sonra Pages projesinin “Custom Domains” bölümünde staging.ornek.com adresini ekleyin ve hangi branch’e bağlandığını belirtin.
Branch tabanlı build komutları için environment variable:
# Production ortamı için
HUGO_ENV: production
HUGO_PARAMS_ENV: production
# Staging için ayrı değerler
HUGO_ENV: staging
Cloudflare Pages’de environment variable’ları “Production” ve “Preview” için ayrı ayrı tanımlayabilirsiniz. Bu sayede staging ortamınızda farklı API endpoint’leri veya analitik konfigürasyonları kullanabilirsiniz.
Build Hook’ları ile Otomatizasyon
CMS’ten veya harici bir sistemden içerik güncellendiğinde otomatik build tetiklemek istiyorsanız Deploy Hook kullanabilirsiniz.
Cloudflare Pages projenizin ayarlarında “Builds & Deployments” bölümünde “Deploy Hooks” kısmından yeni bir hook URL oluşturun.
# Deploy hook'u tetikle (örneğin bir CMS webhook'undan)
curl -X POST "https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/HOOK_ID"
# Cron job ile düzenli rebuild (örneğin her gece yarısı)
# crontab -e ile ekleyin
0 0 * * * curl -X POST "https://api.cloudflare.com/client/v4/pages/webhooks/deploy_hooks/HOOK_ID" >> /var/log/cf-deploy.log 2>&1
Bu yaklaşım özellikle Headless CMS kullanıyorsanız çok işe yarıyor. Contentful, Sanity veya Strapi’den içerik publish edildiğinde otomatik olarak sitenizi rebuild edebilirsiniz.
Performans İzleme ve Analitik
Cloudflare Pages ile birlikte gelen Web Analytics özelliği sizi Google Analytics’e olan bağımlılıktan kurtarabilir. Dashboard’da “Analytics & Logs” bölümünden etkinleştirebilirsiniz.
Sitenize tek satır script eklemek yeterli:
<!-- _headers veya layout dosyanıza ekleyin -->
<!-- Cloudflare Web Analytics -->
<script defer src='https://static.cloudflare.com/beacon.min.js'
data-cf-beacon='{"token": "TOKEN_BURAYA"}'></script>
Bu analytics cookie’siz çalışıyor ve GDPR açısından çok daha temiz bir yaklaşım sunuyor. Ziyaretçilerinize cookie banner göstermek zorunda kalmıyorsunuz.
Core Web Vitals takibi için de Cloudflare’in kendi araçlarını kullanabilirsiniz. “Speed” sekmesinde Observatory aracıyla sitenizi test edebilir, performans sorunlarını tespit edebilirsiniz.
Yaygın Sorunlar ve Çözümleri
Build Başarısız Oluyor
En yaygın sorun yanlış Node.js veya framework versiyonu. Environment variable’larla versiyonları sabitleyin:
# Build environment variables
NODE_VERSION: 18.17.0
NPM_VERSION: 9.6.7
RUBY_VERSION: 3.2.0 # Jekyll için
PYTHON_VERSION: 3.11 # MkDocs için
DNS Propagasyonu Bekleniyor
Custom domain ekledikten sonra SSL sertifikası birkaç dakika içinde hazır olmalı. Eğer uzun süre bekliyorsanız:
# DNS propagasyonunu kontrol et
dig CNAME blog.ornek.com @1.1.1.1
dig CNAME blog.ornek.com @8.8.8.8
# SSL sertifika durumunu kontrol et
curl -I https://blog.ornek.com
404 Sayfaları SPA’da Çalışmıyor
Single Page Application kullanıyorsanız tüm isteklerin index.html‘e yönlendirilmesi gerekiyor:
# _redirects dosyasına ekle
/* /index.html 200
Cache Sorunu
Deployment sonrası eski içerik görünüyorsa Cloudflare cache’ini temizleyin:
# API ile cache temizleme
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache"
-H "Authorization: Bearer API_TOKEN"
-H "Content-Type: application/json"
--data '{"purge_everything": true}'
Production’da purge_everything yerine specific file purge kullanmak daha güvenli. Aksi halde tüm cache temizlenip CDN performansı geçici olarak düşebilir.
Cloudflare Pages Ücretsiz Plan Sınırlılıkları
Ücretsiz planda dikkat etmeniz gerekenler:
- Aylık 500 build limiti var. Küçük projeler için bu yeterli ama çok aktif bir repo için ücretli plana geçmek gerekebilir.
- Concurrent build sayısı 1 ile sınırlı. Aynı anda birden fazla deployment tetiklenirse sıra bekliyor.
- Custom domain sayısı projesi başına 100 ile sınırlı.
- Preview deployment süresi sınırsız, tüm eski preview’lar erişilebilir kalıyor.
Build limitini optimize etmek için branch protection kurallarıyla gereksiz push’ları önleyebilir, ya da sadece belirli branch’leri build için tetiklenecek şekilde yapılandırabilirsiniz.
Sonuç
Cloudflare Pages, özellikle DNS’i zaten Cloudflare üzerinde yönetenler için neredeyse vazgeçilmez bir araç haline geldi. Tek panel üzerinden DNS, SSL, CDN, deployment ve analitik yönetimi gerçekten workflow’u ciddi ölçüde basitleştiriyor.
Dikkat edilmesi gereken en önemli noktalar şunlar: build environment variable’larını doğru ayarlamak, custom domain için CNAME Flattening’in avantajından yararlanmak, _redirects ve _headers dosyalarıyla güvenlik ve redirect yönetimini merkezi tutmak, ve production ile preview ortamları için ayrı environment variable’lar tanımlamak.
Ücretsiz katmanın sunduğu olanaklar küçük ve orta ölçekli projeler için fazlasıyla yeterli. Build limitine takılıyorsanız GitHub Actions veya GitLab CI üzerinden Wrangler CLI ile build alıp Cloudflare’e sadece dosyaları push eden bir yaklaşımla build sayısını optimize edebilirsiniz. Bu şekilde Cloudflare’in kendi build sistemini kullanmadan sadece hosting özelliğinden faydalanabilirsiniz.
