Docker ile Konteynerize Edilmiş Ebeveyn Kayıt Portalı Oluşturma: Tam Yığın Uygulama Dockerlaştırma Rehberi
Günümüz yazılım geliştirme dünyasında, uygulamaların hızlı ve tutarlı bir şekilde dağıtılması kritik öneme sahiptir. Özellikle birden fazla bileşenden oluşan tam yığın (full-stack) uygulamalar için bu durum daha da karmaşık hale gelebilir. Bu makalede, bir ebeveyn kayıt portalı örneği üzerinden, Docker kullanarak tam yığın bir uygulamayı nasıl konteynerize edeceğimizi adım adım inceleyeceğiz. Frontend, backend ve veritabanı katmanlarını izole edilmiş Docker konteynerlerinde çalıştırarak, geliştirme, test ve üretim ortamları arasında tutarlılığı nasıl sağlayacağımızı keşfedeceksiniz.
Konteynerleşmenin Temelleri ve Neden Docker?
Modern yazılım geliştirme süreçlerinde karşılaşılan en büyük zorluklardan biri, “benim makinemde çalışıyor” sendromudur. Geliştiricinin ortamında sorunsuz çalışan bir uygulama, farklı bir sunucuda veya ortamda beklenmedik hatalar verebilir. İşte tam da bu noktada konteynerleşme devreye girer.
Geleneksel Dağıtım Yaklaşımlarının Zorlukları
- Ortam Tutarsızlıkları: Farklı işletim sistemleri, kütüphane versiyonları veya bağımlılıklar nedeniyle oluşan hatalar.
- Kaynak Çatışmaları: Aynı sunucu üzerinde birden fazla uygulamanın farklı bağımlılıkları çakışabilir.
- Yavaş Dağıtım Süreçleri: Uygulamanın tüm bağımlılıklarını manuel olarak kurmak ve yapılandırmak zaman alıcıdır.
- Ölçeklenebilirlik Sorunları: Uygulamanın belirli bir bileşenini bağımsız olarak ölçeklendirmek zordur.
Docker Nedir ve Nasıl Çalışır?
Docker, uygulamaları ve tüm bağımlılıklarını (kod, çalışma zamanı, sistem araçları, kütüphaneler vb.) tek bir izole edilmiş pakette, yani “konteyner” içinde çalıştırmayı sağlayan açık kaynaklı bir platformdur. Sanal makinelerden farklı olarak, Docker konteynerleri ana bilgisayarın işletim sistemi çekirdeğini paylaşır, bu da onları daha hafif ve daha hızlı hale getirir.
Bir Docker konteyneri, bir Docker imajından oluşturulur. Docker imajı, uygulamanın çalışması için gerekli her şeyi içeren statik, salt okunur bir şablondur. Bu imajlar, Dockerfile adı verilen metin dosyaları aracılığıyla tanımlanır.
Konteynerleşmenin Avantajları
- İzolasyon: Her uygulama kendi konteynerinde izole edilmiş bir ortamda çalışır, bu da çakışmaları önler.
- Taşınabilirlik: Bir konteyner imajı, herhangi bir Docker kurulu sistemde aynı şekilde çalışır. “Bir kez inşa et, her yerde çalıştır” felsefesi.
- Tutarlılık: Geliştirme, test ve üretim ortamları arasında tam bir tutarlılık sağlar.
- Hızlı Dağıtım: Uygulama ve bağımlılıkları tek bir pakette olduğu için dağıtım süreçleri hızlanır.
- Kaynak Verimliliği: Sanal makinelere göre daha az kaynak tüketir.
- Ölçeklenebilirlik: İhtiyaç duyulan bileşenlerin kolayca çoğaltılmasına olanak tanır.
Ebeveyn Kayıt Portalı Mimarisi (Örnek Uygulama)
Örnek ebeveyn kayıt portalımız, modern tam yığın uygulamaların tipik bir temsilcisidir. Bu portal, ebeveynlerin çocuklarını okul veya etkinlikler için kaydettirmelerine olanak tanıyan basit bir arayüze sahip olacaktır.
Uygulama Katmanları
Uygulamamız üç ana katmandan oluşacaktır:
- Frontend (Kullanıcı Arayüzü): Ebeveynlerin kayıt formlarını dolduracağı ve bilgileri görüntüleyeceği web arayüzü.
- Backend (API Sunucusu): Frontend’den gelen istekleri işleyen, veritabanı ile iletişim kuran ve iş mantığını içeren API.
- Veritabanı: Ebeveyn ve çocuk kayıt bilgilerini kalıcı olarak depolayan veri depolama katmanı.
Kullanılacak Teknolojiler
Bu rehberde, popüler ve modern teknolojileri kullanarak bir örnek oluşturacağız:
- Frontend: React (
create-react-appile oluşturulmuş) - Backend: Node.js (Express.js çatısı ile)
- Veritabanı: PostgreSQL
Neden Bu Mimarinin Konteynerleşmesi Önemli?
Her bir katmanın farklı bağımlılıkları, çalışma zamanları ve konfigürasyonları vardır. Frontend bir Node.js ortamında derlenip statik dosyalar olarak servis edilirken, backend kendi Node.js çalışma zamanına ihtiyaç duyar ve veritabanı tamamen ayrı bir süreçtir. Bu katmanları ayrı ayrı konteynerize etmek, her bir bileşenin bağımsız olarak geliştirilmesine, test edilmesine ve ölçeklendirilmesine olanak tanır. Ayrıca, farklı geliştiricilerin farklı teknolojilerle çalışmasını kolaylaştırır.
Frontend Uygulamasını Dockerlaştırma
React tabanlı frontend uygulamamızı Dockerize etmek, uygulamanın derlenmesini ve ardından statik dosyalarının bir web sunucusu (örneğin Nginx) aracılığıyla servis edilmesini içerir.
Dockerfile Oluşturma (React + Nginx)
Uygulamanızın kök dizininde Dockerfile adında bir dosya oluşturun:
# Aşama 1: Uygulamayı derle
FROM node:18-alpine AS builder
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . ./
RUN npm run build
# Aşama 2: Derlenmiş dosyaları Nginx ile servis et
FROM nginx:alpine
COPY --from=builder /app/build /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Bu Dockerfile iki aşamalı bir yapı kullanır (multi-stage build):
- İlk aşamada (
builder), Node.js ortamında uygulamanın bağımlılıkları kurulur ve üretim için derlenir. - İkinci aşamada, sadece derlenmiş statik dosyalar hafif bir Nginx imajına kopyalanır. Bu, nihai imaj boyutunu önemli ölçüde küçültür.
docker build ve docker run Komutları
Uygulamanızı derlemek ve bir Docker imajı oluşturmak için:
docker build -t ebeveyn-portal-frontend .
İmajı oluşturduktan sonra, bir konteyner olarak çalıştırmak için:
docker run -p 3000:80 --name ebeveyn-frontend ebeveyn-portal-frontend
Bu komut, yerel makinenizin 3000 numaralı portunu konteynerin 80 numaralı portuna eşler. Artık tarayıcınızdan http://localhost:3000 adresine giderek frontend uygulamanıza erişebilirsiniz.
Backend Uygulamasını Dockerlaştırma
Node.js tabanlı backend uygulamamızı Dockerize etmek, uygulamanın bağımlılıklarını kurmayı ve Node.js çalışma zamanında başlatmayı içerir.
Dockerfile Oluşturma (Node.js + Express)
Backend uygulamanızın kök dizininde Dockerfile adında bir dosya oluşturun:
FROM node:18-alpine
WORKDIR /app
COPY package.json ./
COPY package-lock.json ./
RUN npm install
COPY . .
EXPOSE 5000
CMD ["npm", "start"]
Bu Dockerfile:
node:18-alpinetemel imajını kullanır (hafif bir Node.js imajı).- Çalışma dizinini
/appolarak ayarlar. package.jsonvepackage-lock.jsondosyalarını kopyalar ve bağımlılıkları kurar. Bu, dosya değişikliklerinde bağımlılıkların tekrar indirilmesini önleyerek katmanlı cache'den faydalanır.- Uygulama kodunu kopyalar.
- Uygulamanın dinleyeceği 5000 numaralı portu açar.
- Uygulamayı
npm startkomutuyla başlatır.
Bağımlılık Yönetimi ve Katmanlı Cache
Yukarıdaki Dockerfile'da package.json ve package-lock.json dosyalarını uygulamanın geri kalanından önce kopyalayıp npm install çalıştırmamızın nedeni, Docker'ın katmanlı imaj yapısından faydalanmaktır. Eğer bu dosyalar değişmezse, npm install katmanı yeniden inşa edilmez, bu da imaj oluşturma süresini hızlandırır.
Ortam Değişkenleri ile Konfigürasyon
Backend uygulamaları genellikle veritabanı bağlantı bilgileri, API anahtarları gibi hassas bilgileri ortam değişkenleri aracılığıyla alır. Docker konteynerlerini çalıştırırken bu değişkenleri kolayca sağlayabiliriz:
docker build -t ebeveyn-portal-backend .
docker run -p 5000:5000 \
-e DATABASE_URL="postgresql://user:password@host:port/database" \
--name ebeveyn-backend ebeveyn-portal-backend
-e bayrağı ile ortam değişkenlerini ayarlayabilirsiniz. Daha sonra Docker Compose ile bu süreci daha da basitleştireceğiz.
Veritabanını Docker ile Yönetme
Uygulamamızın veri katmanı olan PostgreSQL'i Docker konteynerinde çalıştırmak, kurulum ve yönetim karmaşıklığını ortadan kaldırır.
Veritabanı Konteynerini Başlatma (PostgreSQL)
PostgreSQL için ayrı bir Dockerfile yazmaya genellikle gerek yoktur, çünkü Docker Hub'da resmi PostgreSQL imajları mevcuttur. Doğrudan docker run komutuyla bir PostgreSQL konteyneri başlatabiliriz:
docker run --name ebeveyn-db \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=ebeveyn_kayit \
-p 5432:5432 \
-d postgres:14-alpine
Bu komut:
ebeveyn-dbadında bir konteyner oluşturur.- Ortam değişkenleri (kullanıcı adı, şifre, veritabanı adı) ile PostgreSQL'i yapılandırır.
- Yerel makinenizin 5432 portunu konteynerin 5432 portuna eşler.
-dbayrağı ile konteyneri arka planda (detached mode) çalıştırır.postgres:14-alpineimajını kullanır (hafif bir PostgreSQL sürümü).
Kalıcı Veri Saklama: Docker Volume'lar
Yukarıdaki komutla başlattığımız veritabanı konteyneri durdurulduğunda veya silindiğinde, içindeki tüm veriler kaybolacaktır. Verilerin kalıcı olması için Docker Volume'ları kullanmalıyız.
docker volume create ebeveyn-db-data
docker run --name ebeveyn-db \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=ebeveyn_kayit \
-p 5432:5432 \
-v ebeveyn-db-data:/var/lib/postgresql/data \
-d postgres:14-alpine
-v ebeveyn-db-data:/var/lib/postgresql/data bayrağı, ebeveyn-db-data adında bir Docker volume'unu PostgreSQL'in veri dizinine bağlar. Bu sayede konteyner silinse bile verileriniz güvende kalır.
Docker Compose ile Çok Katmanlı Uygulama Yönetimi
Üç ayrı konteyneri (frontend, backend, veritabanı) manuel olarak yönetmek karmaşık ve hataya açık olabilir. Docker Compose, çoklu konteyner Docker uygulamalarını tanımlamak ve çalıştırmak için bir araçtır. Tek bir YAML dosyası kullanarak tüm servislerinizi yapılandırabilir ve tek bir komutla başlatıp durdurabilirsiniz.
docker-compose.yml Dosyası Oluşturma
Uygulamanızın kök dizininde docker-compose.yml adında bir dosya oluşturun:
version: '3.8'
services:
frontend:
build:
context: ./frontend # Frontend uygulamasının olduğu dizin
dockerfile: Dockerfile
ports:
- "3000:80"
depends_on:
- backend
networks:
- ebeveyn-network
backend:
build:
context: ./backend # Backend uygulamasının olduğu dizin
dockerfile: Dockerfile
ports:
- "5000:5000"
environment:
DATABASE_URL: postgresql://admin:secret@db:5432/ebeveyn_kayit
depends_on:
- db
networks:
- ebeveyn-network
db:
image: postgres:14-alpine
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
POSTGRES_DB: ebeveyn_kayit
volumes:
- ebeveyn-db-data:/var/lib/postgresql/data
networks:
- ebeveyn-network
volumes:
ebeveyn-db-data:
networks:
ebeveyn-network:
driver: bridge
Bu dosya:
frontend,backendvedbadında üç servis tanımlar.- Her servisin nasıl inşa edileceğini (
build) veya hangi imajı kullanacağını (image) belirtir. - Port eşlemelerini (
ports) yapar. environmentanahtar kelimesi ile ortam değişkenlerini ayarlar (backend'in veritabanına bağlanması için).depends_onile servisler arası bağımlılıkları tanımlar (backend db'ye, frontend backend'e bağlıdır).volumesile veritabanı için kalıcı depolama sağlar.- Tüm servislerin birbirleriyle iletişim kurabilmesi için
ebeveyn-networkadında özel bir ağ oluşturur.
Servisler Arası Ağ İletişimi
Docker Compose, aynı docker-compose.yml dosyasında tanımlanan servisler arasında otomatik olarak bir ağ oluşturur. Bu ağ sayesinde servisler birbirlerine isimleriyle erişebilirler. Örneğin, backend uygulaması veritabanına db hostname'i üzerinden erişebilir (postgresql://admin:secret@db:5432/ebeveyn_kayit).
Uygulamayı Tek Komutla Başlatma ve Durdurma
Tüm uygulamayı başlatmak için, docker-compose.yml dosyasının bulunduğu dizinde aşağıdaki komutu çalıştırın:
docker compose up -d
-d bayrağı, servisleri arka planda başlatır. Uygulamanızı durdurmak ve tüm konteynerleri kaldırmak için:
docker compose down
Bu komutlar, geliştirme sürecinizi inanılmaz derecede hızlandırır ve tüm ekibin aynı ortamda çalışmasını sağlar.
Konteynerize Uygulamanın Avantajları ve Sonraki Adımlar
Ebeveyn kayıt portalımızı Docker ile konteynerize ederek önemli avantajlar elde ettik. Ancak yolculuk burada bitmiyor.
Ölçeklenebilirlik ve Yüksek Erişilebilirlik
Docker Compose ile uygulamayı kolayca çalıştırabiliriz, ancak üretim ortamında daha gelişmiş orkestrasyon araçlarına ihtiyaç duyarız. Kubernetes gibi platformlar, konteynerize edilmiş uygulamaları otomatik olarak ölçeklendirme, yük dengeleme ve kendi kendini iyileştirme yetenekleri sunar. İhtiyaç duyulan backend servislerinin sayısını artırmak veya azaltmak, Kubernetes ile kolayca yönetilebilir.
CI/CD Süreçlerine Entegrasyon
Konteynerleşme, Sürekli Entegrasyon/Sürekli Dağıtım (CI/CD) boru hatlarının temelini oluşturur. Her kod değişikliğinde otomatik olarak Docker imajları oluşturulabilir, test edilebilir ve dağıtım ortamlarına gönderilebilir. Bu, yazılım teslimatını hızlandırır ve insan hatasını minimize eder.
Üretim Ortamına Dağıtım (Kubernetes'e Giriş)
Küçük ölçekli projeler için Docker Compose yeterli olabilirken, büyük ve karmaşık üretim ortamlarında Kubernetes veya Docker Swarm gibi konteyner orkestrasyon araçları vazgeçilmezdir. Bu araçlar, konteynerlerin yaşam döngüsünü yönetir, hata toleransı sağlar ve uygulamanızın yüksek erişilebilirliğini garanti eder.
Sonuç
Bu makalede, bir ebeveyn kayıt portalı örneği üzerinden tam yığın bir uygulamanın Docker ile nasıl konteynerize edileceğini detaylı bir şekilde inceledik. Frontend, backend ve veritabanı katmanlarını ayrı Docker konteynerlerinde çalıştırarak, geliştirme ve dağıtım süreçlerimizi basitleştirdik, ortam tutarsızlıklarını ortadan kaldırdık ve uygulamanın taşınabilirliğini artırdık. Docker Compose ile tüm servisleri tek bir komutla yönetme yeteneği, geliştirici deneyimini önemli ölçüde iyileştirmektedir. Konteynerleşme, modern yazılım geliştirmenin vazgeçilmez bir parçası olup, uygulamalarınızı daha esnek, ölçeklenebilir ve yönetilebilir hale getirmenin anahtarıdır. Bu rehberdeki adımları takip ederek kendi tam yığın uygulamalarınızı Dockerlaştırmaya başlayabilir ve konteyner teknolojisinin sunduğu avantajlardan faydalanabilirsiniz.
SSS (Sık Sorulan Sorular)
Docker image boyutunu nasıl küçültebilirim?
İmaj boyutunu küçültmek için multi-stage build (çok aşamalı derleme) kullanın, gereksiz bağımlılıkları ve dosyaları imaja dahil etmeyin, daha küçük temel imajlar (örneğin alpine versiyonları) kullanın ve .dockerignore dosyası ile gereksiz dosyaları kopyalamayı engelleyin.
Docker volume'lar ne işe yarar?
Docker volume'lar, konteynerlerin dışındaki verileri kalıcı olarak depolamak için kullanılır. Konteyner silinse bile volume'daki veriler korunur. Özellikle veritabanları gibi kalıcı veri gerektiren uygulamalar için hayati öneme sahiptir.
Docker Compose yerine Kubernetes ne zaman kullanmalıyım?
Docker Compose, genellikle tek bir makinede çalışan çoklu konteyner uygulamalarını geliştirme ve test etme için idealdir. Üretim ortamında, yüksek ölçeklenebilirlik, otomatik hata kurtarma, yük dengeleme ve karmaşık dağıtım stratejileri gerektiren durumlarda Kubernetes gibi konteyner orkestrasyon platformları tercih edilmelidir.
Konteynerlerde güvenlik nasıl sağlanır?
Güvenlik için şunlara dikkat edin: En az yetkiye sahip kullanıcılarla konteynerleri çalıştırın, bilinen güvenlik açıklarını içeren eski imajları kullanmaktan kaçının, imajları düzenli olarak güncelleyin, hassas bilgileri ortam değişkenleri yerine Docker Secrets veya Kubernetes Secrets ile yönetin ve konteynerlerin sadece ihtiyaç duydukları portları açmasını sağlayın.
