Modern frontend mühendisliği, on yıl öncesine hiç benzemiyor. Sadece HTML ve CSS yazmıyorsunuz. Tipik bir proje artık belirli bir Node.js çalışma zamanı (runtime), kilitlenmiş bir paket yöneticisi sürümü, karmaşık bir derleme araçları yığını ve her şeyin kusursuz bir şekilde hizalanmasını bekleyen dağıtım (deployment) süreçleriyle birlikte geliyor. İlk npm install komutu ile nihai üretim (production) derlemesi arasında küçük farklar sızar. Bir ekip arkadaşınız Node 20 kullanıyor. Siz Node 18 kullanıyorsunuz. Makinenizdeki global bir CLI aracı, onlardaki eksik bir bağımlılığı gizliyor. Sonra kimsenin duymak istemediği o cümle geliyor: "Benim makinemde çalışıyor."
Docker, bu belirsizliği ortadan kaldırdığı için ön yüz araç setinizde yerini hak ediyor. Uygulamanızı ihtiyaç duyduğu tam çalışma zamanı, sistem kütüphaneleri ve bağımlılıklarla birlikte paketler. İster Windows üzerinde kod yazın, ister macOS üzerinden gönderin, ister bir Linux bulut örneğine (instance) dağıtın; davranış tamamen aynı kalır.
Ön Yüz Geliştiricileri Neden Önemsemeli
Docker'ın çözdüğü sorun noktaları soyut değildir. Her sprint'te karşınıza çıkarlar.
Sürüm çakışmaları zaman kaybettirir. Bir eski müşteri projesi Node 18 gerektirirken, yan projeniz Node 20, yeni girişim (startup) işiniz ise Node 22 gerektirebilir. Konteynerlar olmadan bunu sürüm yöneticileri (version managers) aracılığıyla yönetirsiniz. Bu, sorun çıkana kadar işe yarar. Küçük bir npm sürüm uyuşmazlığı, peer bağımlılıklarının nasıl çözüleceğini değiştirebilir ve sizi başkasında sorunsuz çalışan ancak sizde bozuk bir derleme ile baş başa bırakabilir. Bir framework yeni bir sürüm duyurduğunda, geri bildirim döngüsü iki saatlik yeniden kurulumlardan oluşmamalıdır. Tek bir dosya değişikliği ve bir konteyner yeniden başlatma kadar hızlı olmalıdır.
Global paketler, sessiz sürtünmenin bir başka kaynağıdır. Altı ay öncesinden kalma Angular CLI, Expo veya Prisma'yı global olarak yüklü bulunduruyor olabilirsiniz. Yeni bir geliştirici aynı aracı sıfırdan yükler ve farklı bir sürüm alır. Aniden derleme betikleriniz (build scripts) başka hiçbir yerde görünmeyen uyarılar vermeye başlar. Docker, her şeyi proje bazlı (project-local) tutarak bunu çözer. Node sürümünü Dockerfile dosyanızda tanımlarsınız. Bağımlılıklar, ana işletim sisteminizden izole edilmiş bir şekilde konteyner içinde yüklenir. Dizüstü bilgisayarınız macOS, Windows veya Ubuntu olabilir; uygulama her seferinde tam olarak aynı ortamı görür.
İşe alıştırma (onboarding) avantajlarını görmezden gelmek zordur. Yeni işe alınanların Homebrew kurulumlarını, nvm alias'larını ve global izin düzeltmelerini içeren üç sayfalık bir readme dosyasına ihtiyacı yoktur. Docker'ı yüklerler, depoyu (repository) klonlarlar ve tek bir komut çalıştırırlar. Eskiden bir öğleden sonrasını alan bir kurulum süreci dakikalara iner. Proje değiştirdiklerinde ise hiçbir şey kalıntı bırakmaz. Yetim kalmış global araçlar yok. PATH önceliği için savaşan sürüm yöneticileri yok. Yerel makineleri temiz kalır.
İmajlar ve Konteynerlar: Temeller
Eğer Docker sizin için yeniyse, terminoloji kulağa geldiğinden daha basittir. Bir Docker imajı bir taslaktır (blueprint). Kaynak kodunuzu, Node.js çalışma zamanını, lockfile dosyanızı ve uygulamayı çalıştırmak için gereken tüm bağımlılıkları içerir. Bir konteyner ise bu imajdan oluşturulmuş canlı bir örnektir (instance). İmajı bir tarif, konteyneri ise gerçek yemek olarak düşünün. Tek bir tariften yüz kez aynı keki pişirebilirsiniz. Ana bilgisayarda neyin yüklü olduğuyla endişelenmeden, tek bir imajdan özdeş konteynerlar oluşturabilirsiniz.
Pratik Bir Dockerfile
Somut bir başlangıç noktasına bakalım. Eğer...
