Databaseless ve Serverless Mimari: Repo Tek Kaynak, Yayın Bir Commit
Bu blogun arkasında ne veritabanı var ne de ayakta tutulan bir sunucu. İçerik repodaki MDX dosyaları, yönetim paneli açık kaynak Decap CMS, yayın ise bir commit. Next.js, bir Git deposu ve statik host ile kurulan bu düzenin nasıl çalıştığını, nerede işe yaradığını ve nerede yetmediğini anlatıyorum.

Bu sitenin arkasında bir veritabanı yok. Ayakta tutulan, yama bekleyen bir sunucu da yok. Yazılar repoda duran MDX dosyaları, yönetim paneli tarayıcıda çalışan açık kaynak Decap CMS, yayınlamak ise bir commit atmak.
Serverless'ı herkes biliyor; buna bir de databaseless ekleyin. Aynı düzeni birkaç projede daha kurdum ve kişisel blogdan kurumsal tanıtım sitesine kadar geniş bir alanda işe yarıyor. Bu yazıda kendinecoder.com'u örnek alarak düzenin parçalarını, yayın akışını ve sınırlarını anlatacağım.
Fikir: repo veritabanıdır
Klasik bir CMS'te içerik veritabanında bir satırdır. Panel o satırı yazar, uygulama sunucusu her ziyarette okur ve sayfayı üretir. Üç parça da sürekli ayakta olmak zorundadır.
Burada ise içerik dosyadır. Her yazı content/blog/ altında bir .mdx dosyası; üst kısmındaki frontmatter da o yazının "kolonları":
---
title: "Databaseless ve Serverless Mimari"
date: "2026-10-25"
tags: [Mimari, Databaseless]
coverImage:
src: /images/uploads/databaseless-mimari-kapak.jpg
published: true
---
Yazının gövdesi Markdown. Araya React bileşeni de girebilir.Veritabanının sağladığı her şeyin dosya sisteminde bir karşılığı var:

Dosya adı aynı zamanda slug, yani URL. Çeviri, aynı adla content/en/blog/ altında duran ikinci bir dosya. Görseller public/images/uploads/ içinde ve onlar da repoda. Migration diye bir kavram yok: frontmatter'a yeni bir alan ekleyip build alıyorsunuz.
Parçalar
Düzen dört parçadan oluşuyor ve hiçbiri sizin işlettiğiniz bir sunucu değil.
- Next.js (App Router): Build sırasında
content/klasörünü okur, her dosya için bir sayfa üretir.gray-matterfrontmatter'ı ayırır,next-mdx-remotegövdeyi derler. Çıktı statik HTML. - Decap CMS: Açık kaynak, Git tabanlı bir yönetim paneli.
public/admin/altında duran statik bir sayfa; şeması tek birconfig.ymldosyası. Panelde "kaydet" dediğinizde dosyayı Git sağlayıcısının API'si üzerinden commit eder. - Bir Git deposu: İçeriğin tek kaynağı. GitHub, GitLab, Bitbucket, Gitea; Decap'in desteklediği herhangi biri. Geçmiş, yedek, geri alma ve inceleme (pull request) bedavaya gelir.
- Bir statik host: Push'u görür, build alır, çıktıyı CDN'e dağıtır. Vercel, Netlify, Cloudflare Pages ve benzerleri bu işi aynı şekilde yapıyor; aralarında geçiş bir repo bağlamaktan ibaret. Sunucu yönetimi yok.
Decap'in şeması kısa ve okunabilir:
backend:
name: github # gitlab, bitbucket, gitea da olabilir
repo: kullanici/site
branch: main
media_folder: "public/images/uploads"
public_folder: "/images/uploads"
collections:
- name: "blog"
folder: "content/blog"
create: true
extension: "mdx"
fields:
- { label: "Başlık", name: "title", widget: "string" }
- { label: "Tarih", name: "date", widget: "datetime" }
- { label: "Kapak", name: "coverImage", widget: "image" }
- { label: "Yayınla", name: "published", widget: "boolean" }
- { label: "İçerik", name: "body", widget: "markdown" }Bu kadar. Panelde gördüğünüz form bu dosyadan türüyor; yeni alan istediğinizde buraya bir satır ekliyorsunuz.
Next tarafında içerik okuyucu da sade. Klasördeki dosyaları alıyor, frontmatter'ı ayırıyor, tarihe göre sıralıyor:
export function getAllContent<T>(type: "blog" | "projects") {
const dir = path.join(process.cwd(), "content", type);
return fs
.readdirSync(dir)
.filter((f) => f.endsWith(".mdx"))
.map((f) => {
const { data, content } = matter(fs.readFileSync(path.join(dir, f), "utf-8"));
return { slug: f.replace(/\.mdx$/, ""), frontmatter: data as T, content };
})
.sort((a, b) => Date.parse(b.frontmatter.date) - Date.parse(a.frontmatter.date));
}Sayfa bileşeni generateStaticParams ile tüm slug'ları döndürüyor, Next de her biri için build anında HTML üretiyor. Ziyaret anında çalışan bir sorgu yok.
Yayın akışı: bir yazı nasıl sayfa olur?

/adminadresine giriyorsunuz. Decap, Git sağlayıcınızın OAuth'u ile kimliğinizi doğruluyor. Bunun için Next'te iki küçük API ucu var: biri sağlayıcıya yönlendiriyor, diğeri dönen kodu token'a çeviriyor. Düzenin "sunucu" tarafı bundan ibaret ve o da yalnızca giriş anında çalışıyor.- Yazıyı yazıp kaydediyorsunuz. Decap
content/blog/yazi.mdxdosyasını ve yüklediğiniz görselleri tek commit olarakmaindalına gönderiyor. - Host push'u görüyor,
next buildçalıştırıyor. Bu sırada site haritası da üretiliyor; yeni dosya için ek bir ayar gerekmiyor. - Bir iki dakika içinde sayfa CDN'de. Eski sürüm de bir commit geride duruyor; bir şey bozulursa
git revertile geri dönüyorsunuz.
Panel kullanmak istemeyen biri için akış daha da kısa: editörde dosyayı yazıp git push. Decap sadece kod bilmeyen bir içerik sahibinin aynı işi tarayıcıdan yapabilmesi için orada.
Neden bu düzen?
- Maliyet sıfır. Git sağlayıcılarının ve statik hostların ücretsiz katmanları bu iş için fazlasıyla yeterli. Veritabanı faturası, sunucu faturası yok.
- Yedek ve geçmiş hazır. Her değişiklik bir commit. Kim, ne zaman, neyi değiştirdi sorusunun cevabı
git log. - Saldırı yüzeyi küçük. Ziyaretçinin karşısına çıkan şey statik dosya. SQL yok, oturum yok, yama bekleyen admin uygulaması yok.
- Hızlı. Her sayfa önceden üretilmiş; CDN'den dosya sunuluyor.
- Taşınabilir ve bağımsız. Bütün site bir
git clone. Hosttan sıkılırsanız aynı repo başka bir hostta ya da kendi makinenizde aynen çalışır. Git sağlayıcısını değiştirmek de bir remote adresi değiştirmek. - İnceleme akışı bedava. İçerik de kod gibi pull request ile gelebilir; birden fazla yazar varsa bu büyük rahatlık.
Nerede yetmez?
Düzenin sınırı belli: ziyaretçinin ürettiği veri. Yorum, beğeni, form kaydı, sepet, kullanıcı hesabı gibi şeyler bu mimarinin kapsamı dışında; o veri commit edilecek bir şey değil. Bir blog ya da haber sitesi bunların hiçbiri olmadan da yayınlanır. İsterseniz sonradan hazır bir yorum servisi ya da form servisi bağlarsınız; içerik yine repoda kalır, o servise uğramaz.
Diğer sınırlar:
- Sık değişen veri. Günde onlarca güncellenen fiyat listesi için her değişiklikte build almak yorucu olur.
- Arama ve filtre. Birkaç yüz içeriğe kadar build anında üretilen bir indeks yetiyor; on binlerce kayıtta ayrı bir arama servisi gerekir.
- Eşzamanlı düzenleme. İki kişi aynı dosyayı aynı anda değiştirirse git çakışması yaşanır. Decap editöryal iş akışı (taslak, inceleme, yayın) sunuyor ama Google Docs değil.
- Build süresi. İçerik büyüdükçe build uzar. Birkaç yüz sayfada dakika mertebesinde, sorun değil; on binlerce sayfada artımlı üretime geçmek gerekir.
Kural basit: veriyi siz üretiyorsanız repo; ziyaretçi üretiyorsa veritabanı. İkisini karıştırmayın.
Kimler için?
Kişisel blog, portföy, kurumsal tanıtım sitesi, ürün dokümantasyonu, küçük bir ilan ya da ürün kataloğu, etkinlik sayfası. Ortak özellikleri aynı: içeriği belli birkaç kişi üretiyor, ziyaretçi okuyor. Bu profilde veritabanı taşımak, hiç binmeyeceğiniz bir arabanın sigortasını ödemek gibi.
Ben de artık yeni bir siteye başlarken ilk soruyu şöyle soruyorum: Burada ziyaretçinin ürettiği bir veri var mı? Yoksa repo yetiyor.
Sizin sitenizde veritabanı gerçekten gerekli mi, yoksa alışkanlıktan mı orada? Yorumlarda konuşalım. İyi kodlamalar!
Muhammed Emin Özdemir
VakıfBank'ta senior full-stack geliştirici. Kurumsal sistemler, temiz kod ve LLM tabanlı araçlar üzerine odaklanıyor.
Hakkımda daha fazlası →
Yorumlar
İlk yorumu siz yapın