Takip et

CI/CD Nedir? Gerçek Bir Pipeline Örneği ile A’dan Z’ye Açıklamalı Kılavuz

Modern yazılım geliştirme dünyasında hız, kalite ve güvenilirlik, rekabet avantajı sağlamanın temel taşları haline gelmiştir.

CI/CD Nedir? Gerçek Bir Pipeline Örneği ile A’dan Z’ye Açıklamalı Kılavuz

Modern yazılım geliştirme dünyasında hız, kalite ve güvenilirlik, rekabet avantajı sağlamanın temel taşları haline gelmiştir. Peki, bir yazılım projesini geliştirme aşamasından son kullanıcıya ulaştırma sürecini nasıl hızlandırabilir, hataları minimuma indirebilir ve sürekli olarak değer sunabiliriz? İşte bu noktada CI/CD devreye giriyor. Bu kapsamlı rehberde, CI/CD’nin ne olduğunu, neden bu kadar önemli olduğunu ve gerçek bir senaryo üzerinden adım adım nasıl çalıştığını keşfedeceğiz. Eğer yazılım geliştirme süreçlerinizi optimize etmek ve daha verimli hale getirmek istiyorsanız, doğru yerdesiniz.

Yazılım Geliştirme Süreçlerinin Evrimi ve CI/CD İhtiyacı

Yazılım dünyası sürekli bir değişim ve gelişim içinde. Geçmişte, yazılım projeleri genellikle “şelale modeli” (waterfall model) gibi geleneksel yaklaşımlarla yönetilirdi. Bu modellerde, planlama, tasarım, geliştirme, test etme ve dağıtım gibi aşamalar ardışık olarak ilerlerdi. Bir aşama bitmeden diğerine geçilmezdi ve bu durum, özellikle büyük projelerde uzun geliştirme döngülerine, geç teslimlere ve son dakika hatalarına yol açabiliyordu. Müşteri geri bildirimleri genellikle projenin sonlarına doğru alındığı için, değişiklik yapmak hem zor hem de maliyetli oluyordu. Bu durum, yazılımın pazara sunulma süresini (time-to-market) uzatıyor ve iş dünyasının hızına ayak uydurmayı zorlaştırıyordu.

Zamanla, daha çevik (agile) metodolojiler ortaya çıktı. Çevik yaklaşımlar, kısa geliştirme döngüleri (sprintler), sürekli geri bildirim ve adaptasyona odaklanarak bu sorunların üstesinden gelmeye çalıştı. Ancak çevik olmanın tek başına yeterli olmadığı anlaşıldı. Geliştiriciler kodlarını sık sık birleştirdiklerinde (integrate), bu birleşimler genellikle “birleşim cehennemi” (integration hell) olarak adlandırılan karmaşık ve hataya açık durumlar yaratabiliyordu. Farklı geliştiricilerin aynı anda farklı özellikler üzerinde çalışması, kod çakışmalarına, uyumluluk sorunlarına ve uzun hata ayıklama süreçlerine neden oluyordu. Her yeni özellik veya hata düzeltmesi, manuel test ve dağıtım süreçleri nedeniyle yine de önemli bir zaman alabiliyordu. İşte bu noktada, yazılım geliştirme ve teslimat süreçlerini otomatikleştirme ihtiyacı doğdu. CI/CD, tam da bu ihtiyaca cevap veren, yazılımın daha hızlı, daha güvenilir ve daha sık bir şekilde müşteriye ulaştırılmasını sağlayan bir dizi ilke ve uygulama bütünüdür. Bu sayede, yazılım geliştirme ekipleri, sürekli entegrasyon (Continuous Integration), sürekli teslimat (Continuous Delivery) ve sürekli dağıtım (Continuous Deployment) pratiklerini benimseyerek, modern iş dünyasının beklentilerini karşılayabilecek çevikliği ve hızı yakalayabilirler.

CI/CD’nin Temel Taşları: Sürekli Entegrasyon ve Sürekli Teslimat/Dağıtım

CI/CD, aslında iki ana bölümden oluşan bir süreçler bütünüdür: Sürekli Entegrasyon (Continuous Integration – CI) ve Sürekli Teslimat (Continuous Delivery – CD) veya Sürekli Dağıtım (Continuous Deployment – CD). Bu iki kavram, modern yazılım geliştirme döngüsünün temelini oluşturur ve birlikte kullanıldığında büyük bir sinerji yaratır.

Sürekli Entegrasyon (Continuous Integration – CI) Nedir?

Sürekli Entegrasyon (CI), geliştiricilerin kod değişikliklerini merkezi bir depoya (örneğin Git tabanlı bir sistem) düzenli ve sık aralıklarla birleştirmeleri (merge) pratiğidir. Geleneksel yaklaşımlarda, geliştiriciler uzun süreler boyunca kendi kodları üzerinde çalışır ve sonra tüm değişiklikleri bir kerede birleştirmeye çalışırlardı. Bu durum, büyük kod çakışmalarına ve birleşme hatalarına yol açarak “birleşim cehennemi” yaşanmasına neden olurdu. CI, bu sorunları ortadan kaldırmayı hedefler. Geliştiriciler, genellikle günde birkaç kez, hatta her küçük değişiklikten sonra kodlarını ana dala (main branch) gönderirler (push).

Her kod gönderimi (push) veya birleştirme (merge) işleminden sonra, otomatik bir sistem devreye girer. Bu sistem, yeni eklenen kodu mevcut kod tabanıyla birleştirir, projeyi derler (build eder) ve bir dizi otomatik test (birim testleri, entegrasyon testleri vb.) çalıştırır. Bu testler, yeni kodun mevcut işlevselliği bozup bozmadığını veya yeni hatalar içerip içermediğini kontrol eder. Eğer derleme veya test aşamalarından herhangi biri başarısız olursa, ekip anında bilgilendirilir. Bu sayede hatalar, geliştirme sürecinin çok erken aşamalarında tespit edilir ve düzeltilir. Erken tespit edilen hatalar, hem düzeltilmesi daha kolay hem de daha az maliyetlidir. CI’ın temel amacı, kod tabanının her zaman çalışır durumda ve kararlı kalmasını sağlamaktır. Bu pratik, geliştiricilerin güvenle kod yazmasına olanak tanır ve entegrasyon kaynaklı sorunların önüne geçer.

Sürekli Teslimat (Continuous Delivery – CD) ve Sürekli Dağıtım (Continuous Deployment – CD) Nedir?

Sürekli Teslimat (CD), CI sürecini bir adım öteye taşıyarak, kodun başarılı bir şekilde derlenip test edildikten sonra, her zaman dağıtıma hazır bir durumda olmasını sağlar. Yani, her başarılı CI döngüsünün ardından, yazılım bir test veya hazırlık (staging) ortamına otomatik olarak dağıtılabilir hale gelir. Bu aşamada, insan müdahalesi olmadan, tek bir tuşa basarak veya basit bir komutla yazılımın canlı (production) ortama geçirilmesi mümkündür. Sürekli Teslimat, yazılımın manuel onay gerektiren son dağıtım adımı hariç tüm süreçlerini otomatikleştirir. Bu, ürün yöneticilerinin veya operasyon ekiplerinin, istedikleri zaman, güvenle yeni bir sürümü canlıya alabilmelerine olanak tanır. Böylece, yeni özellikler ve hata düzeltmeleri çok daha hızlı bir şekilde son kullanıcılara ulaştırılabilir.

Sürekli Dağıtım (CD) ise, Sürekli Teslimat’ın tam otomatize edilmiş halidir. Bu modelde, CI ve CD süreçleri başarıyla tamamlandıktan sonra, herhangi bir insan müdahalesi veya onayı olmaksızın, yazılım otomatik olarak canlı (production) ortama dağıtılır. Yani, bir geliştirici kodunu ana dala gönderir, bu kod başarılı bir şekilde derlenir, tüm testleri geçer ve ardından doğrudan son kullanıcının erişebileceği ortama dağıtılır. Sürekli Dağıtım, yazılım teslimatını en üst düzeyde hızlandırır ve pazara sunma süresini (time-to-market) önemli ölçüde kısaltır. Ancak bu yaklaşım, çok yüksek otomasyon, kapsamlı test kapsamı ve güçlü izleme (monitoring) sistemleri gerektirir. Herhangi bir hata durumunda hızlı geri alma (rollback) yeteneği de kritik öneme sahiptir. Genellikle, yüksek güvene sahip ve olgunlaşmış ekipler tarafından tercih edilen bir yaklaşımdır. Her iki CD yaklaşımı da, yazılımın değerini müşteriye daha hızlı ve daha güvenilir bir şekilde ulaştırmayı hedeflerken, Sürekli Dağıtım bu süreci tamamen otomatikleştirerek insan faktörünü ortadan kaldırır.

CI/CD Neden Modern Yazılım Geliştirme İçin Vazgeçilmezdir?

CI/CD pratikleri, günümüz rekabetçi iş dünyasında yazılım geliştiren her kuruluş için adeta bir zorunluluk haline gelmiştir. Bu sistemlerin sunduğu avantajlar, sadece teknik ekipleri değil, tüm iş birimlerini ve son kullanıcıları da olumlu yönde etkiler. Peki, CI/CD’yi bu kadar vazgeçilmez kılan temel nedenler nelerdir?

  • Hız ve Çeviklik: CI/CD, yazılımın geliştirme aşamasından canlı ortama geçiş süresini (time-to-market) önemli ölçüde kısaltır. Otomatikleştirilmiş derleme, test ve dağıtım süreçleri sayesinde, yeni özellikler ve hata düzeltmeleri çok daha hızlı bir şekilde kullanıcılara sunulabilir. Bu durum, işletmelerin pazar değişikliklerine daha hızlı adapte olmasını ve rekabet avantajı elde etmesini sağlar. Geliştiriciler, kodlarını sürekli entegre ettikleri için, küçük ve sık değişiklikler yapma konusunda daha cesur olurlar, bu da çevikliği artırır.
  • Geliştirilmiş Kod Kalitesi ve Güvenilirlik: Sürekli Entegrasyon ile her kod değişikliği otomatik testlerden geçer. Birim testleri, entegrasyon testleri ve hatta performans testleri gibi farklı test türleri, hataların ve potansiyel sorunların erken aşamada tespit edilmesini sağlar. Bu, canlı ortama ulaşan kodun daha sağlam ve güvenilir olmasını garantiler. Erken hata tespiti, “birleşim cehennemi” gibi durumları önler ve hata ayıklama süresini azaltır. Sonuç olarak, son kullanıcıya sunulan ürünün kalitesi artar.
  • Maliyet ve Zaman Tasarrufu: Manuel olarak yapılan derleme, test ve dağıtım işlemleri hem zaman alıcı hem de hataya açıktır. CI/CD’nin otomasyon yetenekleri sayesinde, bu tekrarlayan görevler otomatik olarak gerçekleştirilir. Geliştiriciler ve operasyon ekipleri, manuel işlerle uğraşmak yerine daha yaratıcı ve stratejik görevlere odaklanabilirler. Hataların erken tespiti, proje ilerledikçe düzeltme maliyetlerinin katlanarak artmasını engeller. Uzun vadede, bu durum önemli ölçüde maliyet ve zaman tasarrufu sağlar.
  • Daha Hızlı Geri Bildirim Döngüsü: CI/CD sayesinde, yeni özellikler veya hata düzeltmeleri canlı ortama daha sık ulaştırılabilir. Bu, müşterilerden ve paydaşlardan daha hızlı geri bildirim alınmasını sağlar. Alınan geri bildirimler, ürünün sonraki iterasyonlarında dikkate alınarak daha kullanıcı odaklı ve değerli bir ürün geliştirilmesine olanak tanır. Hızlı geri bildirim döngüsü, ürünün pazar ihtiyaçlarına daha iyi uyum sağlamasına yardımcı olur.
  • Geliştirici Mutluluğu ve Verimliliği: Geliştiriciler, kodlarının hızlı ve otomatik bir şekilde test edilip dağıtıldığını bilmekten memnuniyet duyarlar. Manuel süreçlerin getirdiği sıkıntı ve stres ortadan kalkar. Hataların erken tespiti, geliştiricilerin sorunları daha hızlı çözmesini ve daha az hayal kırıklığı yaşamasını sağlar. Bu durum, geliştirici motivasyonunu ve genel ekip verimliliğini artırır. Otomasyon, geliştiricilerin tekrarlayan işler yerine daha yaratıcı kodlama görevlerine odaklanmasına imkan tanır.
  • Daha İyi İşbirliği ve Şeffaflık: CI/CD, geliştirme, test ve operasyon (DevOps) ekipleri arasındaki işbirliğini teşvik eder. Tüm ekip, yazılımın durumu hakkında sürekli güncel bilgiye sahip olur. Otomatikleştirilmiş süreçler, herkes için daha şeffaf bir ortam yaratır ve potansiyel darboğazları veya sorunları daha görünür kılar. Bu, ekiplerin daha uyumlu çalışmasına ve ortak hedeflere ulaşmasına yardımcı olur.

Özetle, CI/CD sadece bir otomasyon aracı değil, aynı zamanda modern yazılım geliştirme felsefesinin temel bir bileşenidir. Yazılımın kalitesini, teslimat hızını ve ekip verimliliğini artırarak, işletmelerin dijital dönüşüm yolculuğunda başarılı olmaları için kritik bir rol oynar.

Bir CI/CD Hattı (Pipeline) Nasıl Çalışır? Adım Adım İnceleme

Bir CI/CD hattı (pipeline), yazılım geliştirme sürecinin her aşamasını otomatikleştiren bir dizi adımdan oluşur. Bu adımlar, kodun yazılmasından başlayıp, test edilip, son kullanıcıya dağıtılmasına kadar uzanır. Her aşama, bir önceki aşamanın başarılı bir şekilde tamamlanmasına bağlıdır. İşte tipik bir CI/CD hattının temel aşamaları ve nasıl çalıştıkları:

1. Kaynak Kodu Yönetimi (Source Code Management – SCM)

Her şey, geliştiricinin kodunu bir sürüm kontrol sistemine (Version Control System – VCS) göndermesiyle başlar. Genellikle Git tabanlı sistemler (GitHub, GitLab, Bitbucket, Azure DevOps Repos) kullanılır. Geliştiriciler, özellik dallarında (feature branches) çalışır ve tamamladıklarında bu değişiklikleri ana dala (main/master branch) birleştirme isteği (pull request/merge request) açarlar. CI/CD hattı, bu tür bir birleştirme isteği veya doğrudan ana dala yapılan bir gönderim (push) tetiklendiğinde otomatik olarak başlar.

2. Derleme (Build) Aşaması

Kod başarıyla sürüm kontrol sistemine gönderildikten sonra, CI/CD hattının ilk otomatik adımı derleme (build) aşamasıdır. Bu aşamada, yazılan kaynak kodu çalıştırılabilir bir formata dönüştürülür. Bu, bir Java projesi için JAR/WAR dosyası oluşturmak, bir .NET projesi için DLL/EXE derlemek, bir Node.js projesi için bağımlılıkları yüklemek (npm install) ve JavaScript/CSS dosyalarını sıkıştırmak (minify) veya bir Docker imajı (image) oluşturmak anlamına gelebilir. Derleme aşamasında, gerekli tüm bağımlılıklar indirilir ve kodun sözdizimi (syntax) hataları kontrol edilir. Eğer bu aşamada bir hata oluşursa (örneğin, derleme hatası veya eksik bağımlılık), pipeline durdurulur ve geliştiriciye geri bildirim sağlanır.

# Örnek bir Node.js projesi için derleme adımları
npm install # Bağımlılıkları yükle
npm run build # Projeyi derle (örneğin React uygulaması için)

3. Test Aşaması

Derleme başarılı olduktan sonra, yazılımın doğru çalıştığından emin olmak için otomatik testler devreye girer. Bu, CI/CD hattının en kritik aşamalarından biridir ve farklı test türlerini içerebilir:

  • Birim Testleri (Unit Tests): Kodun en küçük, bağımsız parçalarını (fonksiyonlar, metotlar) test eder. Hızlı çalışır ve geliştirme aşamasında hataları erken yakalamak için çok etkilidir.
  • Entegrasyon Testleri (Integration Tests): Farklı modüllerin veya servislerin birbiriyle doğru bir şekilde iletişim kurup kurmadığını test eder.
  • Fonksiyonel Testler (Functional Tests): Yazılımın belirli bir işlevselliği gereksinimlere uygun olarak yerine getirip getirmediğini doğrular.
  • Kabul Testleri (Acceptance Tests): Son kullanıcının bakış açısından yazılımın beklenen davranışları sergileyip sergilemediğini kontrol eder.
  • Performans Testleri (Performance Tests): Yazılımın yük altında nasıl davrandığını, yanıt süresini ve ölçeklenebilirliğini ölçer.
  • Güvenlik Taramaları (Security Scans): Statik Kod Analizi (SAST) veya Dinamik Kod Analizi (DAST) araçları kullanılarak potansiyel güvenlik açıklarını tespit eder.

Tüm bu testler otomatik olarak çalıştırılır. Herhangi bir testin başarısız olması durumunda, pipeline durdurulur ve geliştiricilere hata raporu gönderilir. Bu, hatalı kodun bir sonraki aşamaya geçmesini engeller.

# Örnek bir Node.js projesi için test adımları
npm test # Birim ve entegrasyon testlerini çalıştır
# Cypress veya Selenium ile uçtan uca (end-to-end) testleri çalıştır

4. Dağıtım (Deployment) Aşaması – Sürekli Teslimat

Testler başarıyla tamamlandıktan sonra, yazılımın dağıtıma hazır olduğu anlamına gelir. Sürekli Teslimat (Continuous Delivery) modelinde, bu aşamada yazılım bir veya daha fazla hazırlık (staging) ortamına otomatik olarak dağıtılır. Bu ortamlar, canlı ortama çok benzerdir ve son kontrollerin, manuel testlerin veya ürün yöneticileri tarafından yapılan onayların gerçekleştirilmesi için kullanılır. Bu aşama genellikle bir insan onayı gerektirir; yani, yazılımın canlı ortama geçirilip geçirilmeyeceğine dair karar manuel olarak verilir.

5. Dağıtım (Deployment) Aşaması – Sürekli Dağıtım

Sürekli Dağıtım (Continuous Deployment) modelinde ise, hazırlık ortamına dağıtımın ardından herhangi bir manuel onay olmaksızın, yazılım otomatik olarak canlı (production) ortama dağıtılır. Bu, her başarılı kod değişikliğinin doğrudan son kullanıcılara ulaştığı anlamına gelir. Bu model, yüksek otomasyon seviyesi, kapsamlı testler ve güçlü izleme (monitoring) sistemleri gerektirir, çünkü herhangi bir sorun durumunda hızlı geri alma (rollback) yeteneği kritik öneme sahiptir. Dağıtım aşaması, sunuculara kodun kopyalanması, kapsayıcıların (Docker) dağıtılması, Kubernetes gibi orkestrasyon araçlarının kullanılması veya sunucusuz (serverless) fonksiyonların güncellenmesi gibi çeşitli yöntemlerle gerçekleştirilebilir.

# Örnek bir Docker ve Kubernetes dağıtım adımı
docker build -t my-app:latest . # Docker imajı oluştur
docker push my-app:latest # İmajı Docker Registry'ye gönder
kubectl apply -f kubernetes/deployment.yaml # Kubernetes'e dağıt

6. İzleme (Monitoring) ve Geri Bildirim

Yazılım canlı ortama dağıtıldıktan sonra CI/CD hattı bitmez. Canlı ortamdaki uygulamanın performansı, hataları ve kullanıcı deneyimi sürekli olarak izlenir (monitor edilir). Loglama (logging) ve metrik (metrics) toplama araçları kullanılır. Herhangi bir sorun tespit edildiğinde, ilgili ekiplere (geliştiriciler, operasyon) otomatik olarak uyarılar gönderilir. Bu geri bildirimler, geliştirme döngüsünün bir sonraki iterasyonunda dikkate alınarak ürünün sürekli olarak iyileştirilmesini sağlar. Bu, DevOps kültürünün “sürekli iyileştirme” (continuous improvement) ilkesinin önemli bir parçasıdır.

Bu adımlar bütünü, yazılımın güvenli, hızlı ve tutarlı bir şekilde geliştirilmesini ve teslim edilmesini sağlar. Her aşamanın otomatize edilmesi, insan hatası riskini azaltır ve ekiplerin daha değerli işlere odaklanmasına olanak tanır.

Gerçek Bir CI/CD Pipeline Örneği: Mikroservis Tabanlı Web Uygulaması

Şimdi, öğrendiğimiz teorik bilgileri gerçek dünya bir senaryo üzerinden somutlaştıralım. Basit bir mikroservis tabanlı web uygulaması için bir CI/CD pipeline’ı nasıl kuracağımızı adım adım inceleyelim. Bu örnekte, bir Node.js tabanlı API servisi ve bir React tabanlı kullanıcı arayüzü (frontend) uygulaması olduğunu varsayalım. Her iki uygulama da ayrı Git depolarında (repositories) bulunuyor ve Docker konteynerleri (containers) içinde çalışacak, Kubernetes üzerinde dağıtılacak.

Senaryo Detayları:

  • Uygulama: Basit bir “Yapılacaklar Listesi” (Todo List) uygulaması.
  • Backend: Node.js (Express.js) ile yazılmış REST API. Kendi Git deposu var.
  • Frontend: React ile yazılmış kullanıcı arayüzü. Kendi Git deposu var.
  • Veritabanı: PostgreSQL (bu örnekte doğrudan CI/CD hattına dahil edilmeyecek, mevcut olduğu varsayılacak).
  • Sürüm Kontrol Sistemi: GitLab.
  • Kapsayıcılaştırma: Docker.
  • Orkestrasyon: Kubernetes.
  • CI/CD Aracı: GitLab CI/CD.

CI/CD Pipeline Adımları (Frontend Uygulaması İçin Örnek):

Bu örnekte, React frontend uygulamasının GitLab deposuna bir kod değişikliği gönderildiğinde tetiklenecek bir GitLab CI/CD pipeline’ını ele alacağız. Backend için de benzer adımlar uygulanacaktır.

1. Kod Değişikliği ve Tetikleyici (Trigger)

Bir geliştirici, React uygulamasında yeni bir özellik ekler veya bir hatayı düzeltir. Değişikliklerini yerel olarak test ettikten sonra, feature/yeni-ozellik adlı bir daldan ana dala (main) bir “merge request” (birleştirme isteği) açar ve kodu GitLab deposuna gönderir (git push).

# Geliştiricinin terminalinde
git checkout -b feature/yeni-ozellik
# Kod değişiklikleri yapılır...
git add .
git commit -m "Yeni görev ekleme özelliği eklendi"
git push origin feature/yeni-ozellik
# GitLab üzerinden merge request oluşturulur.

GitLab, bu merge request’in açıldığını veya ana dala bir kod gönderimi yapıldığını algılar ve otomatik olarak .gitlab-ci.yml dosyasında tanımlanan CI/CD pipeline’ını tetikler.

2. CI Aşaması: Derleme ve Test

GitLab CI, pipeline’ı çalıştırmak için bir Runner (koşucu) başlatır. Bu Runner, projenin kaynak kodunu çeker ve aşağıdaki adımları gerçekleştirir:

a. Bağımlılıkları Yükleme ve Derleme (Build)

Runner, React projesi için gerekli Node.js bağımlılıklarını yükler ve uygulamanın üretim için derlenmiş (built) statik dosyalarını oluşturur.

# .gitlab-ci.yml dosyasında ilgili kısım
build_job:
  stage: build
  image: node:16 # Node.js 16 imajını kullan
  script:
    - npm install # Bağımlılıkları yükle
    - npm run build # React uygulamasını derle (dist/build klasörü oluşur)
  artifacts: # Derlenen dosyaları sonraki aşamalara aktar
    paths:
      - build/
    expire_in: 1 day

Bu adımda herhangi bir bağımlılık hatası veya derleme sorunu yaşanırsa, pipeline başarısız olur ve geliştiriciye bilgi verilir.

b. Testler

Derleme başarılı olduktan sonra, otomatik testler çalıştırılır. Bu testler, yeni eklenen kodun mevcut işlevselliği bozmadığından emin olmak için kritik öneme sahiptir.

# .gitlab-ci.yml dosyasında ilgili kısım
test_job:
  stage: test
  image: node:16
  script:
    - npm install
    - npm test # Birim ve entegrasyon testlerini çalıştır (örneğin Jest ile)
    # - npx cypress run # Uçtan uca testler (varsa)
  dependencies:
    - build_job # build_job'dan gelen artifact'ları kullan

Eğer herhangi bir test başarısız olursa, pipeline durur ve geliştiriciye hatanın nerede olduğu bildirilir. Bu sayede hatalar, canlı ortama ulaşmadan çok önce tespit edilir ve düzeltilir.

3. CD Aşaması: Kapsayıcılaştırma ve Dağıtım

Tüm derleme ve test adımları başarıyla geçildikten sonra, uygulama dağıtıma hazır hale gelir.

a. Docker İmajı Oluşturma ve Kayıt Defterine Gönderme

Uygulamanın derlenmiş statik dosyaları (önceki aşamadan gelen artifact’lar), bir Docker imajı içine yerleştirilir. Bu imaj, uygulamanın tüm bağımlılıklarını ve çalışma zamanı ortamını içerir, böylece her ortamda tutarlı bir şekilde çalışması sağlanır. Oluşturulan imaj, bir Docker kayıt defterine (Registry – örneğin GitLab Container Registry veya Docker Hub) gönderilir.

# .gitlab-ci.yml dosyasında ilgili kısım
docker_build_push_job:
  stage: deploy
  image: docker:latest # Docker CLI imajını kullan
  services:
    - docker:dind # Docker in Docker servisini başlat
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY # GitLab Registry'ye giriş
    - docker build -t $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -t $CI_REGISTRY_IMAGE:latest . # İmajı oluştur
    - docker push $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA # Belirli commit SHA'lı imajı gönder
    - docker push $CI_REGISTRY_IMAGE:latest # latest etiketli imajı gönder
  dependencies:
    - build_job
  only:
    - main # Sadece main branch'e merge edildiğinde çalıştır
b. Hazırlık (Staging) Ortamına Dağıtım (Sürekli Teslimat)

Oluşturulan Docker imajı, Kubernetes kümesindeki hazırlık (staging) ortamına dağıtılır. Bu dağıtım, Kubernetes manifest dosyaları (Deployment, Service) kullanılarak yapılır.

# .gitlab-ci.yml dosyasında ilgili kısım
deploy_staging_job:
  stage: deploy
  image: alpine/helm:3.8.1 # Helm veya kubectl CLI imajı
  script:
    - kubectl config use-context <your-kubernetes-context> # Kubernetes bağlamını ayarla
    - kubectl set image deployment/frontend-app frontend=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n staging # Yeni imajla dağıtımı güncelle
  environment:
    name: staging
    url: https://staging.example.com
  when: on_success # Önceki aşamalar başarılı olursa
  only:
    - main

Bu noktada, ürün yöneticileri veya QA ekibi, hazırlık ortamındaki uygulamayı manuel olarak test edebilir ve canlıya geçiş için onay verebilir.

c. Canlı (Production) Ortamına Dağıtım (Sürekli Dağıtım – İsteğe Bağlı Onaylı)

Eğer Sürekli Dağıtım kullanılıyorsa ve hazırlık ortamındaki testler başarılı bulunursa, uygulama otomatik olarak veya manuel bir onay adımıyla canlı ortama dağıtılır. Bu adım genellikle en hassas olanıdır ve manuel onay adımı eklemek, riski azaltmak için yaygın bir pratiktir.

# .gitlab-ci.yml dosyasında ilgili kısım
deploy_production_job:
  stage: deploy
  image: alpine/helm:3.8.1
  script:
    - kubectl config use-context <your-kubernetes-context>
    - kubectl set image deployment/frontend-app frontend=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA -n production
  environment:
    name: production
    url: https://app.example.com
  when: manual # Manuel onay gerektirir
  only:
    - main

when: manual ifadesi, bu adımın sadece bir kullanıcı tarafından GitLab arayüzünden tetiklenmesiyle çalışacağını belirtir. Bu, Sürekli Teslimat modelinin bir parçasıdır ve canlı dağıtım üzerinde daha fazla kontrol sağlar.

4. İzleme ve Geri Bildirim

Canlıya alınan uygulama, Prometheus, Grafana, ELK Stack gibi araçlarla sürekli izlenir. Herhangi bir hata veya performans sorunu durumunda, ekiplere otomatik uyarılar gönderilir. Bu geri bildirimler, geliştirme döngüsünün bir sonraki iterasyonunda iyileştirmeler yapmak için kullanılır.

Bu örnek, modern bir web uygulamasının CI/CD pipeline’ının nasıl yapılandırılabileceğine dair temel bir bakış sunmaktadır. Her projenin kendine özgü ihtiyaçları olsa da, temel adımlar ve prensipler genellikle aynı kalır.

CI/CD Uygulamasında Dikkat Edilmesi Gerekenler ve İleri Düzey Konular

CI/CD pipeline’ını kurmak ve çalıştırmak, modern yazılım geliştirmenin temel bir parçasıdır. Ancak bu süreci gerçekten optimize etmek ve en iyi verimi almak için bazı önemli noktalara dikkat etmek ve ileri düzey konuları göz önünde bulundurmak gerekir.

1. Kapsamlı Otomatik Testler: CI/CD’nin Kalbi

CI/CD’nin temel amacı, güvenilirliği artırmaktır. Bu güvenilirliğin en önemli bileşeni ise kapsamlı ve otomatik testlerdir. Sadece birim testleriyle yetinmemek, entegrasyon, fonksiyonel, uçtan uca (end-to-end – E2E) ve performans testlerini de pipeline’a dahil etmek kritik öneme sahiptir. Test piramidi yaklaşımını benimseyerek, alt seviye testleri (birim) çok sayıda ve hızlı bir şekilde, üst seviye testleri (E2E) ise daha az sayıda ve yavaş bir şekilde çalıştırmak en verimli yöntemdir. Unutmayın, testleriniz ne kadar eksiksiz olursa, otomatik dağıtıma olan güveniniz de o kadar artar.

2. Güvenlik Entegrasyonu: DevSecOps

Güvenlik, CI/CD sürecinin ayrılmaz bir parçası olmalıdır. Geliştirme döngüsünün sonuna bırakılan güvenlik kontrolleri, maliyetli ve zaman alıcı hatalara yol açabilir. Bunun yerine, “Shift Left” (güvenliği sola kaydırma) prensibiyle, güvenlik taramalarını pipeline’ın erken aşamalarına dahil etmek önemlidir:

  • Statik Uygulama Güvenlik Testi (SAST): Kod yazılırken veya derlenirken potansiyel güvenlik açıklarını (SQL injection, XSS vb.) tarar.
  • Dinamik Uygulama Güvenlik Testi (DAST): Çalışan uygulamayı dışarıdan tarayarak güvenlik açıklarını bulur.
  • Bağımlılık Taraması: Kullanılan üçüncü taraf kütüphanelerdeki bilinen güvenlik açıklarını (CVE’ler) kontrol eder.
  • Kapsayıcı Güvenliği: Docker imajlarındaki güvenlik zafiyetlerini tarar.

Bu entegrasyon, DevSecOps kültürünün bir parçasıdır ve yazılımın baştan sona güvenli olmasını sağlar.

3. Geri Alma (Rollback) Mekanizmaları

En iyi testlere rağmen, canlı ortamda beklenmedik sorunlar ortaya çıkabilir. Bu gibi durumlarda, hızlı bir geri alma (rollback) mekanizmasına sahip olmak hayati önem taşır. CI/CD pipeline’ınız, önceki kararlı sürüme hızlıca geri dönebilme yeteneğine sahip olmalıdır. Bu genellikle, bir önceki başarılı dağıtımın Docker imajını veya uygulama sürümünü tekrar dağıtarak yapılır. Otomatik geri alma seçenekleri de (örneğin, izleme sistemleri belirli bir hata eşiğini aştığında otomatik geri alma) düşünülebilir.

4. Ortam Yönetimi ve Tutarlılık

Geliştirme, test, hazırlık (staging) ve canlı (production) ortamlarının mümkün olduğunca birbirine benzer olması (parite) önemlidir. “Altyapı Kod Olarak” (Infrastructure as Code – IaC) prensipleri (Terraform, Ansible gibi araçlarla) kullanılarak ortamların otomatik olarak sağlanması ve yapılandırılması, ortamlar arası farklılıklardan kaynaklanan hataları minimize eder. Her ortam için aynı dağıtım mekanizmalarının kullanılması da tutarlılığı artırır.

5. Kapsayıcı Teknolojileri ve Orkestrasyon

Docker gibi kapsayıcı teknolojileri, uygulamaların ve bağımlılıklarının paketlenmesini standartlaştırarak “benim makinemde çalışıyor” sorununu ortadan kaldırır. Kubernetes gibi kapsayıcı orkestrasyon araçları ise, bu kapsayıcıların büyük ölçekte yönetilmesini, dağıtılmasını, ölçeklenmesini ve izlenmesini otomatikleştirir. CI/CD pipeline’ınızın Docker imajları oluşturup bir kayıt defterine göndermesi ve ardından Kubernetes’e dağıtması, modern uygulamalar için güçlü bir kombinasyondur.

6. İzleme, Loglama ve Uyarı Sistemleri

Uygulama canlıya alındıktan sonra, CI/CD sürecinin son adımı izleme ve geri bildirimdir. Prometheus ile metrik toplama, Grafana ile görselleştirme, ELK Stack (Elasticsearch, Logstash, Kibana) ile log yönetimi ve PagerDuty gibi araçlarla uyarı sistemleri kurmak, uygulamanın sağlığını sürekli olarak takip etmenizi sağlar. Anormallikler veya hatalar durumunda otomatik uyarılar almak, sorunlara hızlıca müdahale etme ve potansiyel kesintileri önleme yeteneği sunar.

7. Pipeline Hızı ve Optimizasyonu

Uzun süren CI/CD pipeline’ları, geliştirici verimliliğini düşürebilir. Pipeline’ı hızlandırmak için:

  • Paralel Çalıştırma: Testleri ve derleme adımlarını paralel olarak çalıştırmak.
  • Önbellekleme (Caching): Bağımlılıkları veya derleme çıktılarını önbelleğe almak.
  • Minimal İmajlar: Docker imajlarını mümkün olduğunca küçük tutmak.
  • Aşamalı Dağıtım (Progressive Delivery): Canary dağıtımı, mavi/yeşil dağıtım gibi yöntemlerle riski azaltırken dağıtım hızını korumak.

Bu ileri düzey konular ve dikkat edilmesi gereken noktalar, CI/CD yatırımınızdan maksimum fayda sağlamanıza yardımcı olacaktır. Sürekli öğrenme ve pipeline’ınızı sürekli iyileştirme, bu sürecin ayrılmaz bir parçasıdır.

Sıkça Sorulan Sorular (SSS)

1. CI/CD sadece büyük şirketler için mi uygundur?

Hayır, CI/CD pratikleri her boyuttaki yazılım ekibi ve projesi için uygundur. Küçük ekipler ve start-up’lar bile CI/CD otomasyonundan büyük faydalar sağlayabilir. Erken benimsenmesi, projenin büyümesiyle birlikte yaşanabilecek karmaşıklıkları yönetmeyi kolaylaştırır ve uzun vadede maliyet tasarrufu sağlar.

2. CI/CD kurmak ne kadar sürer ve ne kadar zordur?

CI/CD kurma süresi ve zorluğu, projenin büyüklüğüne, mevcut altyapıya ve ekibin deneyimine bağlıdır. Basit bir proje için temel bir pipeline birkaç saat içinde kurulabilirken, karmaşık mikroservis mimarileri veya özel altyapılar için haftalar sürebilir. Başlangıçta temel adımlarla başlamak ve zamanla geliştirmek en iyi yaklaşımdır. GitLab CI/CD, GitHub Actions gibi araçlar, başlangıç için nispeten kolay entegrasyon sunar.

3. CI/CD kullanmak DevOps ile aynı şey midir?

Hayır, CI/CD, DevOps’un bir parçasıdır ancak tamamı değildir. DevOps, yazılım geliştirme (Development) ve operasyon (Operations) ekipleri arasındaki işbirliğini, kültürü ve araçları kapsayan daha geniş bir felsefedir. CI/CD ise, bu felsefenin otomasyon ve teslimat süreçlerine odaklanan temel pratiklerinden biridir. DevOps, CI/CD’nin ötesinde izleme, geri bildirim, altyapı kod olarak (IaC) gibi birçok başka prensibi de içerir.

4. Hangi CI/CD araçlarını kullanmalıyım?

Piyasada birçok popüler CI/CD aracı bulunmaktadır. Seçiminiz projenizin ihtiyaçlarına, kullandığınız sürüm kontrol sistemine ve bütçenize göre değişebilir:

  • Jenkins: Açık kaynaklı, çok esnek ve geniş eklenti desteğine sahip. Ancak kurulumu ve yönetimi daha karmaşık olabilir.
  • GitLab CI/CD: GitLab ile entegre, kolay kurulum ve kullanımı olanaklı.
  • GitHub Actions: GitHub depolarıyla sorunsuz entegrasyon, YAML tabanlı yapılandırma.
  • Azure DevOps Pipelines: Microsoft ekosistemine entegre, hem bulut hem de şirket içi çözümler sunar.
  • CircleCI, Travis CI: Bulut tabanlı, hızlı ve kullanımı kolay çözümler.

Küçük projeler için genellikle GitLab CI/CD veya GitHub Actions gibi entegre çözümler iyi bir başlangıç noktasıdır.

5. CI/CD’ye geçiş yaparken en büyük zorluklar nelerdir?

CI/CD’ye geçişte karşılaşılan başlıca zorluklar şunlardır: Mevcut manuel süreçlerin otomasyona dönüştürülmesi, yeterli test kapsamının oluşturulması, altyapı ve ortam tutarlılığının sağlanması, güvenlik entegrasyonu ve ekip üyelerinin yeni araçlara ve pratiklere adapte olması. Ayrıca, pipeline’ın sürekli izlenmesi ve iyileştirilmesi de sürekli bir çaba gerektirir. Kültürel değişim, bu zorlukların üstesinden gelmede anahtar rol oynar.

Sonuç

CI/CD, modern yazılım geliştirme dünyasının vazgeçilmez bir parçasıdır. Geliştirme süreçlerini otomatikleştirerek, kod kalitesini artırır, hata oranlarını düşürür ve yazılımın pazara sunulma süresini önemli ölçüde kısaltır. Sürekli Entegrasyon (CI) ile geliştiricilerin kodlarını sık sık birleştirmesi ve otomatik testlerden geçirmesi sağlanırken, Sürekli Teslimat/Dağıtım (CD) ile yazılımın güvenle ve hızlıca canlı ortama ulaştırılması hedeflenir. Bu süreçler, ekiplerin daha verimli çalışmasına, daha hızlı geri bildirim almasına ve son kullanıcıya sürekli olarak değer sunmasına olanak tanır.

Bir web uygulaması örneği üzerinden gördüğümüz gibi, CI/CD pipeline’ı, kod değişikliğinden başlayarak derleme, test, kapsayıcılaştırma ve dağıtım adımlarını kapsar. Bu adımların her biri, yazılımın kararlılığını ve güvenilirliğini garanti altına almak için otomatize edilir. Başarılı bir CI/CD uygulaması, sadece teknik bir otomasyon değil, aynı zamanda kapsamlı test stratejileri, güvenlik entegrasyonu, etkili izleme ve geri alma mekanizmaları gibi ileri düzey konuları da içerir. Unutulmamalıdır ki, CI/CD bir kere kurulup bırakılacak bir sistem değil, sürekli olarak iyileştirilmesi ve optimize edilmesi gereken dinamik bir süreçtir. Bu sayede, yazılım geliştirme ekipleri, değişen pazar koşullarına hızla adapte olabilir ve rekabet avantajını sürdürebilirler.

#CI/CD #DevOps #SürekliEntegrasyon #SürekliTeslimat #YazılımGeliştirme #Otomasyon

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.