GitLab CI/CD Pipeline Oluşturma Rehberi

📅 3 Ocak 2026Emre Karabulut
⏱️ Yaklaşık 11 dakikalık okuma süresi

GitLab CI/CD Pipeline Oluşturma Rehberi

Modern yazılım geliştirme süreçlerinde hız, güvenilirlik ve otomasyon vazgeçilmez unsurlardır. Sürekli Entegrasyon (CI) ve Sürekli Dağıtım (CD) pratikleri, bu hedeflere ulaşmak için kritik öneme sahiptir. GitLab, entegre bir SCM (Source Code Management) ve CI/CD platformu olarak geliştiricilere projelerini uçtan uca yönetme imkanı sunar.

Bu rehberde, GitLab CI/CD’nin temel prensiplerini, pipeline yapısını ve projenizde nasıl etkili bir şekilde kullanabileceğinizi adım adım inceleyeceğiz. Amaç, kodunuzu otomatik olarak test eden, derleyen ve dağıtan sağlam bir pipeline oluşturmaktır.

GitLab CI/CD Nedir ve Neden Kullanmalıyız?

Sürekli Entegrasyon (CI): Geliştiricilerin kod değişikliklerini ana depoya sık sık entegre etme pratiğidir. Her entegrasyon, otomatik testler ile doğrulanır, böylece hatalar erken aşamada tespit edilir.

Sürekli Dağıtım (CD): CI aşamasını geçen kodun, otomatik olarak üretim ortamına veya bir ara ortama dağıtılmasıdır. Sürekli Dağıtım, genellikle Sürekli Teslimat’ı (Continuous Delivery) da kapsar, ki bu da kodun her an dağıtıma hazır olduğu anlamına gelir.

GitLab CI/CD kullanmanın başlıca faydaları:

  • Otomasyon: Manuel hataları azaltır, tekrarlayan görevleri otomatikleştirir.
  • Hız: Kod değişikliklerini daha hızlı entegre eder ve dağıtır, pazar süresini kısaltır.
  • Güvenilirlik: Her değişiklik otomatik testlerden geçtiği için hatalar erken yakalanır, üretimdeki sorunlar minimize edilir.
  • Tutarlılık: Dağıtım süreçleri her zaman aynı şekilde işler, ortamlar arası farklılıklar azalır.
  • Görünürlük: Pipeline durumu herkes tarafından izlenebilir, geliştirme ve operasyon ekipleri arasında şeffaflık sağlanır.

.gitlab-ci.yml Dosyası: Pipeline’ınızın Kalbi

GitLab CI/CD pipeline’ınızın tüm tanımlamaları, projenizin kök dizininde bulunan .gitlab-ci.yml adlı bir YAML dosyasında yapılır. Bu dosya, GitLab Runner tarafından okunur ve pipeline’ın nasıl çalışacağını belirler.

Bir .gitlab-ci.yml dosyası genellikle şunları içerir:

  • stages: Pipeline’daki mantıksal aşamaların sırası.
  • jobs: Her aşamada çalışacak bağımsız görevler.
  • scripts: Her job içinde çalıştırılacak komutlar.
  • image: Job’ların çalışacağı Docker imajı.
  • cache, artifacts, variables: Performans ve veri yönetimi için yardımcı anahtarlar.

Temel Yapı Taşları

1. Stages (Aşamalar)

Pipeline’ınızın akışını tanımlayan mantıksal gruplardır. Job’lar, tanımlanan aşamalar içinde çalışır ve bir aşamadaki tüm job’lar başarılı olmadan bir sonraki aşama başlamaz (varsayılan davranış).


stages:
  - build      # Uygulamayı derle
  - test       # Testleri çalıştır
  - deploy     # Uygulamayı dağıt

Bu örnekte, önce build aşamasındaki tüm job’lar, ardından test aşamasındaki job’lar ve son olarak deploy aşamasındaki job’lar çalışacaktır.

2. Jobs (Görevler)

Pipeline’ınızın çalıştırdığı en küçük bağımsız birimlerdir. Her job, belirli bir stage‘e atanır ve bir dizi script komutu çalıştırır. Job’lar varsayılan olarak aynı aşamadaki diğer job’larla paralel olarak çalışır.


build_frontend_job:
  stage: build
  script:
    - echo "Frontend uygulaması derleniyor..."
    - npm install
    - npm run build

run_unit_tests:
  stage: test
  script:
    - echo "Birim testleri çalıştırılıyor..."
    - npm test -- --coverage

3. Script (Komutlar)

Her job içinde çalıştırılacak Shell komutlarıdır. Birden fazla komut alt alta yazılabilir. Her komut ayrı bir satırda yazılmalıdır.


deploy_production:
  stage: deploy
  script:
    - echo "Üretim ortamına dağıtım başlatılıyor..."
    - scp -r build/* user@your-production-server:/var/www/html/app/
    - ssh user@your-production-server "systemctl restart nginx"
    - echo "Dağıtım tamamlandı."

4. Image (Docker İmajı)

Her job’ın çalışacağı ortamı belirleyen Docker imajıdır. Bu, farklı projeler için izole ve tutarlı ortamlar sağlamanın harika bir yoludur. Job seviyesinde veya global olarak tanımlanabilir.


build_job:
  image: node:18-alpine # Node.js 18 ve Alpine Linux tabanlı bir imaj
  stage: build
  script:
    - npm install
    - npm run build

Global bir imaj tanımlayarak tüm job’ların aynı imajı kullanmasını sağlayabilirsiniz:


image: python:3.10-slim

stages:
  - lint
  - test

lint_code:
  stage: lint
  script:
    - pip install flake8
    - flake8 .

run_pytest:
  stage: test
  script:
    - pip install pytest
    - pytest

Yardımcı Anahtarlar ve Optimize Edici Ayarlar

1. Variables (Değişkenler)

Pipeline’ınızda yeniden kullanılabilir değerler tanımlamanızı sağlar. Proje ayarları veya hassas bilgiler (CI/CD ayarlarında maskelenebilir/korunabilir) için kullanışlıdır. GitLab’ın ön tanımlı değişkenleri (CI_COMMIT_BRANCH, CI_PROJECT_DIR vb.) de mevcuttur.


variables:
  FRONTEND_APP_PATH: frontend/my-app
  BUILD_OUTPUT_DIR: build

build_frontend:
  stage: build
  script:
    - cd $FRONTEND_APP_PATH
    - npm install
    - npm run build
    - mv $BUILD_OUTPUT_DIR ../../

2. Cache (Önbellek)

Job’lar arasında veya farklı pipeline çalıştırmaları arasında bağımlılıkları (örneğin node_modules veya pip_cache) önbelleğe almanızı sağlar. Bu, pipeline’ın daha hızlı çalışmasını ve tekrar eden indirme işlemlerini engeller.


cache:
  paths:
    - node_modules/ # node_modules klasörünü önbelleğe alır
  key: ${CI_COMMIT_REF_SLUG} # Branch'e özgü önbellek anahtarı

build_job:
  stage: build
  script:
    - npm install
    - npm run build

3. Artifacts (Ürünler)

Bir job’ın çıktısını (derlenmiş dosyalar, test raporları, log dosyaları vb.) sonraki job’lar veya indirme için saklamanızı sağlar. Genellikle expire_in ile ömrü belirlenir.


build_app:
  stage: build
  script:
    - make build
  artifacts:
    paths:
      - dist/ # dist klasörünü artifact olarak sakla
      - app.log
    expire_in: 1 day # Artifact'ler 1 gün sonra otomatik silinecek

deploy_to_server:
  stage: deploy
  script:
    - echo "Artifact'ler kullanılarak dağıtım yapılıyor..."
    - cp -r dist/* /var/www/app/ # Önceki job'dan gelen dist klasörünü kullan

4. only / except / rules

Job’ların hangi durumlarda çalışacağını kontrol etmenizi sağlar. Dallara (branches), etiketlere (tags) veya dosya değişikliklerine göre filtreleme yapabilirsiniz. rules, only/except‘e göre daha esnek ve güçlü bir alternatiftir ve karmaşık koşulları ifade etmek için kullanılır.


# only/except örnekleri
deploy_production_legacy:
  stage: deploy
  script:
    - echo "Eski yöntemle prod'a dağıtım..."
  only:
    - main # Sadece 'main' dalında çalış
  when: manual # Manuel olarak çalıştırılır

deploy_feature_branch:
  stage: deploy
  script:
    - echo "Özellik dalına dağıtım..."
  except:
    - main # 'main' dalı hariç tüm dallarda çalışır

# rules ile daha gelişmiş koşullar
build_develop:
  stage: build
  script:
    - echo "Geliştirme dalı için derleme..."
  rules:
    - if: $CI_COMMIT_BRANCH == "develop" # Eğer dal 'develop' ise
      when: always # Her zaman çalıştır
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Eğer MR tetiklediyse
      when: manual # Manuel çalıştır
      allow_failure: true # Başarısız olursa pipeline'ı durdurma

deploy_to_production:
  stage: deploy
  script:
    - echo "Üretim ortamına güvenli dağıtım..."
  rules:
    - if: $CI_COMMIT_BRANCH == "main" && $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/ # Eğer 'main' dalı ve bir sürüm etiketi varsa
      when: manual # Manuel olarak çalıştır
      allow_failure: false

Örnek Bir CI/CD Pipeline: Basit Bir Web Uygulaması

Şimdi, basit bir Node.js tabanlı web uygulamasını derleyen, test eden ve iki farklı ortama (staging ve production) dağıtan tam bir .gitlab-ci.yml örneği oluşturalım.


image: node:18-alpine # Tüm job'lar için Node.js 18 imajı

variables:
  # Uygulamanın olduğu dizin
  APP_SOURCE_DIR: ./frontend-app

stages:
  - build
  - test
  - deploy

# Uygulamayı derleme job'ı
build_frontend:
  stage: build
  script:
    - echo "Frontend uygulaması derleniyor..."
    - cd $APP_SOURCE_DIR
    - npm install # Bağımlılıkları yükle
    - npm run build # Uygulamayı derle
  artifacts:
    paths:
      - $APP_SOURCE_DIR/build/ # Derlenmiş dosyaları sonraki aşamalar için sakla
    expire_in: 1 hour # Artifact'ler 1 saat sonra silinsin
  cache:
    paths:
      - $APP_SOURCE_DIR/node_modules/ # node_modules'i önbelleğe al

# Uygulama test job'ı
test_frontend:
  stage: test
  script:
    - echo "Frontend testleri çalıştırılıyor..."
    - cd $APP_SOURCE_DIR
    - npm test # Testleri çalıştır
  allow_failure: false # Testler başarısız olursa pipeline durur
  cache:
    paths:
      - $APP_SOURCE_DIR/node_modules/
    policy: pull # Sadece önbelleği çek, güncelleme

# Staging ortamına dağıtım job'ı
deploy_to_staging:
  stage: deploy
  script:
    - echo "Staging ortamına dağıtım yapılıyor..."
    # Burada SSH veya başka bir dağıtım aracı ile staging sunucusuna kopyalama komutları olabilir
    - ls -la $APP_SOURCE_DIR/build/ # Örnek olarak artifact içeriğini listele
    - echo "Dağıtım başarılı: Staging Ortamı."
  environment:
    name: staging
    url: https://staging.my-app.com # GitLab UI'da link olarak görünür
  rules:
    - if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_BRANCH == "develop" # main veya develop dalında otomatik çalış
      when: on_success # Önceki aşamalar başarılı ise
    - if: $CI_PIPELINE_SOURCE == "merge_request_event" # Merge Request'lerde de çalışabilir
      when: on_success

# Production ortamına manuel dağıtım job'ı
deploy_to_production:
  stage: deploy
  script:
    - echo "Üretim ortamına dağıtım yapılıyor..."
    # Gerçek bir senaryoda bu adımda daha gelişmiş dağıtım stratejileri (Kubernetes, Blue/Green, Canary) kullanılır.
    - echo "Üretim dağıtımı tamamlandı."
  environment:
    name: production
    url: https://my-app.com
  rules:
    - if: $CI_COMMIT_BRANCH == "main" # Sadece main dalında
      when: manual # Kullanıcı tarafından manuel olarak tetiklenmeli
      allow_failure: false # Başarısız olursa pipeline durur

Bu örnekte:

  • build_frontend job’ı uygulamayı derler, bağımlılıkları önbelleğe alır ve derlenmiş çıktıları (build/ klasörü) artifact olarak depolar.
  • test_frontend job’ı testleri çalıştırır. Testler başarısız olursa, pipeline durur.
  • deploy_to_staging job’ı main veya develop dallarına yapılan her push’ta otomatik olarak staging ortamına dağıtım yapar.
  • deploy_to_production job’ı sadece main dalında ve kullanıcı tarafından manuel olarak tetiklendiğinde çalışır. Bu, üretim dağıtımları üzerinde daha fazla kontrol sağlar.

En İyi Uygulamalar (Best Practices)

  • Küçük ve Odaklı Job’lar: Her job tek bir sorumluluğa sahip olmalı (derleme, test, statik analiz, dağıtım). Bu, pipeline’ı daha anlaşılır ve yönetilebilir kılar.
  • İmajları Kullanın: Tutarlı ve izole ortamlar sağlamak için Docker imajları kullanın. Gerekirse projenize özel Docker imajları oluşturun.
  • Önbellekleme ve Artifact’ler: Pipeline hızını artırmak için bağımlılıkları önbelleğe alın (node_modules, vendor, .m2 vb.) ve job çıktılarını (derlenmiş kod, raporlar) artifact olarak saklayın.
  • Değişkenleri Kullanın: Tekrarlayan değerler, yapılandırma ayarları ve hassas bilgiler için değişkenler tanımlayın. Hassas bilgileri GitLab CI/CD ayarlarında korumalı ve maskelenmiş değişkenlerde saklayın.
  • Testleri Ciddiye Alın: Test aşaması başarısız olursa pipeline’ın durmasını sağlayın (allow_failure: false varsayılandır). Bu, hatalı kodun ileri gitmesini engeller.
  • Gelişmiş Koşullar için rules: Job’ları koşullu olarak çalıştırmak için only/except yerine daha güçlü ve esnek olan rules anahtarını kullanın.
  • Ortamları Tanımlayın: Dağıtım job’ları için environment anahtarını kullanarak dağıtım ortamlarını izleyin. Bu, geçmiş dağıtımları ve ortam durumunu takip etmenize yardımcı olur.
  • Pipeline Görselleştirmesini Kullanın: GitLab UI’daki pipeline görselleştirmesini akışı anlamak, bağımlılıkları görmek ve hataları gidermek için aktif olarak kullanın.
  • Linting ve Validasyon: .gitlab-ci.yml dosyanızı düzenlerken GitLab’ın dahili CI linter aracını kullanarak sözdizimi hatalarını kontrol edin.

Sonuç

GitLab CI/CD, yazılım geliştirme süreçlerinizi otomatikleştirmenize, hızlandırmanıza ve güvenilirliğini artırmanıza olanak tanıyan güçlü bir araçtır. .gitlab-ci.yml dosyasını doğru bir şekilde yapılandırarak, projeniz için özel ihtiyaçlara uygun, esnek ve verimli pipeline’lar oluşturabilirsiniz.

Bu rehber, GitLab CI/CD yolculuğunuzda size bir başlangıç noktası sunmayı amaçlamaktadır. Denemeler yapmaktan, GitLab dokümantasyonunu keşfetmekten ve geniş GitLab topluluğundan yardım almaktan çekinmeyin. Otomatikleşmiş ve sorunsuz bir dağıtım süreci dileğiyle!

Emre Karabulut
📊 Bu yazı 4 kez okundu.