Şubat ayında platformdaki görevime başladığım hafta, ekibe yeni bir geliştiricinin katılmasına denk geldim. Kurulum dokümanı 14 sayfalık, en son 2023'te güncellenmiş bir wiki sayfasıydı. PHP sürümü tutmadı, eksik bir extension yüzünden composer patladı, MySQL'in charset ayarı farklı çıktı... Arkadaşın ilk commit'i atması üç buçuk gün sürdü. Aynı ekipte iki ay sonra, ortam docker compose'a taşındıktan sonra işe başlayan geliştirici ilk günün öğleden sonrasında PR açıyordu.
"Bende çalışıyor" cümlesi sektörün en pahalı cümlelerinden biri. Faturası tek kalemde görünmediği için kimse toplamıyor: kurulum günleri, "sende hangi sürüm var?" mesajlaşmaları, sadece tek bir kişinin makinesinde tekrarlanabilen hayalet buglar, tatildeki adamın laptop'una uzak masaüstüyle bağlanmalar. Docker bu faturayı sıfırlamıyor ama kalemlerin çoğunun üstünü çiziyor.
Ortam Kurulumu Doküman Değil, Kod Olmalı
Wiki'deki kurulum dokümanının kaderi bellidir: yazıldığı gün doğrudur, üç ay sonra kısmen doğrudur, bir yıl sonra aktif olarak zarar verir. Çünkü dokümanı güncellemek kimsenin işi değildir. compose.yaml ise farklı bir sözleşmedir: çalışmazsa CI kırılır, kırılınca biri hemen düzeltir. Ortam tanımı kod olunca güncel kalmak zorunda kalır; bütün mesele bu zorunluluğu kurmak.
Bizim projelerimizde standart şu: repo'yu klonla, docker compose up de, kahveni al. Veritabanı, Redis, kuyruk, mail yakalayıcı (Mailpit'in hayatımızda kapladığı yeri ayrıca sevgiyle analım), hepsi ayakta ve tohum veriyle dolu. Yeni başlayan birine artık "ortamı kur" demiyoruz; "compose up de, takılırsan ses et" diyoruz. Ses eden de pek çıkmıyor.
Buradaki incelik tohum verisi. Boş veritabanıyla ayağa kalkan ortam yarım iştir; geliştirici anlamlı bir ekran görebilmek için yarım gün elle veri girer. Seed script'ine yatırım yapın: gerçekçi ama anonim veri, birkaç farklı senaryoyu kapsayan kayıtlar. Bu yatırım her yeni geliştiricide ve her "temiz ortamda deneyeyim" anında geri döner.
Compose'un az bilinen nimeti profiller: herkesin her gün ihtiyaç duymadığı servisleri — Elasticsearch, raporlama servisi, o devasa analitik konteyneri — ayrı profile alın ki standart up hafif kalsın, ihtiyacı olan tek bayrakla açsın. Sekiz servisin hepsini her sabah ayağa kaldırmak, laptop fanından tanıdığınız o geliştirici mutsuzluğunun baş sebebi.
Üretimle Birebir Aynı Olmak Zorunda mı?
Sık gelen soru: "Prod'da Kubernetes var, yerelde de mi kuralım?" Hayır. Yerel ortamın amacı üretimin minyatürü olmak değil, davranışsal eşdeğerlik: aynı PHP ya da Node sürümü, aynı veritabanı motoru ve major sürümü, aynı kritik konfigürasyon. Orkestrasyon katmanını yerelde taklit etmeye çalışmak, çözdüğünden çok dert açıyor.
Öte yandan imaj tarafında paralellik kurmaya değer: yerelde kullandığınız Dockerfile ile CI'da test koşan ve üretim imajını üreten Dockerfile aynı aileden olsun. Multi-stage build ile tek dosyadan hem geliştirme hem üretim hedefi çıkarmak bizim standart kalıbımız; böylece "yerelde geçen test CI'da patladı" sürprizlerinin en büyük kaynağı kuruyor.
Ama sürüm eşitliğinden taviz vermeyin. "Yerelde MySQL 8.0, prod'da 8.4, ne fark eder" diyen bir ekibin, iki sürüm arasındaki tek bir davranış değişikliği yüzünden yarım gün kaybettiğini yakından izledik. Farkı fark ettiğiniz an compose dosyasındaki tek satırı değiştirip ekibin tamamına aynı anda dağıtabiliyor olmanız zaten Docker'ın bütün olayı.
Bir uyarı da şuraya: compose dosyası bir kere yazılıp unutulursa o da wiki dokümanının kaderine yaklaşır. Üretime Redis eklendiyse compose'a da eklenecek; bu disiplini kod review'un parçası yapın, kimsenin insafına bırakmayın.
Mac'te Yavaş, Windows'ta Tuhaf: Gerçekleri Konuşalım
Dürüst olmak gerekirse Docker'ın yerel geliştirmedeki en büyük sürtünmesi hep performans oldu, özellikle macOS'te dosya senkronizasyonu. Volume mount üzerinden çalışan büyük bir Laravel projesinin Mac'te sürünmesi yıllarca şaka konusuydu. Bugün tablo çok daha iyi: VirtioFS tarafındaki iyileştirmeler, alternatif runtime'lar (birkaç projede OrbStack kullanıyoruz, ekip memnun) ve akıllıca ayrılmış volume'lar sorunu büyük ölçüde çözüyor. vendor ve node_modules gibi ağır klasörleri named volume'a alıp host'tan ayırmak hâlâ en etkili tek numara.
Windows tarafında WSL2 işleri düzeltti ama bir şartla: proje dosyaları WSL dosya sisteminin içinde duracak. Dosyaları Windows tarafında tutup WSL üzerinden mount eden kurulumların yavaşlığı, "Docker kötüymüş" diye yanlış hükme vardıran klasik tuzak.
Küçük ama günlük hayatı belirleyen ayrıntılar da var. Sürümleri sabitleyin; mysql:latest yazan compose dosyası, bir sabah herkesin ortamını sessizce değiştirir. Servislerinize healthcheck tanımlayın ve bağımlılıkları ona bağlayın; yoksa uygulama, veritabanı daha ayaklanmadan bağlanmaya çalışıp ilk açılışta kafa karıştıran hatalar üretir. Port çakışmaları için de .env ile öneklenmiş portlar kullanın — aynı makinede iki ayrı projenin ortamını çalıştıran ekiplerde bu küçük disiplin günde birkaç küfür tasarrufu sağlıyor.
Gizli bilgiler için de kısa bir hatırlatma: repoya .env.example girer, gerçek .env asla girmez ve compose dosyasına API anahtarı gömülmez. "Yerel ortam nasılsa" rahatlığıyla konteynere yazılan bir üretim anahtarının repo geçmişine sızması, temizlemesi en sevimsiz kazalardan. Ekip komutlarını da tek kapıya toplayın — bizde her projede aynı görev dosyası var: kur, test, sıfırla. Hangi projeye geçersen geç, kaslar aynı.
Veri kalıcılığının klasik kazasını da not edeyim: docker compose down -v komutundaki o masum -v bayrağı, volume'ları da siler — yani üç gündür üzerinde çalıştığınız test verinizi. Ekipte herkesin başına bir kez geliyor, sonra kimse unutmuyor. Bizim çözümümüz veriyi sıfırlamayı bilinçli bir komuta bağlamak: make reset deyince silinip yeniden tohumlanıyor, onun dışında hiçbir gündelik komut veriye dokunmuyor.
Aynı Ortamı Artık Ajanlar da Kullanıyor
Son bir yılın bize öğrettiği yepyeni bir gerekçe daha var. Agentic geliştirme gündelik hale geldi; kod yazan ajanlar test koşuyor, migration deniyor, servisleri ayağa kaldırıp logları okuyor. Bir ajana "testleri çalıştır" diyebilmeniz için ortamın tek komutla, deterministik şekilde kurulabiliyor olması şart. İnsan geliştirici eksik dokümanı sorup öğrenir; ajan ya çuvallar ya da — daha kötüsü — tahmin eder ve tahminiyle iş yapar.
Bizim ekipte her ajan oturumu kendi izole compose ortamında çalışıyor. Ajan bir şeyi bozarsa ortam çöpe gidiyor, otuz saniyede yenisi ayağa kalkıyor. Bu rahatlık, "bende çalışıyor"un son kalesi olabilecek "ama ajanın ortamında çalışmıyor" devrini daha açılmadan kapattı.
Ekibinizde ortam kurulumu hâlâ günler sürüyorsa ya da "bende çalışıyor" cümlesi haftalık ritüele dönüştüyse, tesellim şu: mevcut bir projeyi compose tabanlı standarda taşımak çoğu zaman bir haftalık iş ve kendini daha ilk ayında amorti ediyor. Bu tür dönüşümleri konuşmayı severim; iletişim sayfası açık.