[ OK ]Çekirdek başlatılıyor...
~/im/blog
Benimle Çalışın

Konuşalım

Birlikte çalışmakla ilgileniyor ya da bir sorunuz mu var? Yeni projeleri konuşmaya her zaman açığım.

İletişime geçin

Bağlantı Kurun

Beni sosyal medyada ve profesyonel ağlarda bulabilirsiniz.

Gizlilik Politikası (KVKK)Kullanım Koşulları
© 2026 Irfan MiralGeliştirici:irfanMiral.com
AnasayfaHakkımda/ÖzgeçmişBlogİletişim
2026-01-22• 5 dakika okuma

Küçük Projelerin Çoğu İçin Yeten Bir GitLab CI/CD Pipeline'ı

DevOps GitLab CI/CD Otomasyon

Hiç CI'ı olmayan küçük bir projeyi devraldığımda, deployment genelde birinin SSH ile girip son commit'i çekmesi ve bir servisi elle restart etmesi anlamına geliyor. Çalışıyor, ta ki bir gün çalışmayana kadar: unutulan bir npm install, yanlış branch'ten bir deploy, ya da atlanmış bir environment variable yüzünden. Çözüm bir düzine stage'i olan karmaşık bir pipeline değil. Her seferinde aynı üç şeyi yapan kısa bir .gitlab-ci.yml: build, test, deploy.

Genel hali

stages:
  - build
  - test
  - deploy

variables:
  GIT_DEPTH: 1

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/

build:
  stage: build
  image: node:20
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/
    expire_in: 1 hour

test:
  stage: test
  image: node:20
  script:
    - npm ci
    - npm run test -- --ci

GIT_DEPTH: 1, uzun geçmişi olan repo'larda checkout'ları hızlı tutuyor, ve node_modules'u branch'e göre cache'lemek, çoğu pipeline'ın full reinstall'dan kaçınması demek. Build stage'i, deploy stage'inin yeniden kullandığı bir artifact üretiyor, yani kod stage başına değil, pipeline başına bir kere build ediliyor.

SSH üzerinden deploy

Küçük projeler için bir Kubernetes manifest'i ya da container registry, projenin ihtiyacından fazla altyapı oluyor çoğu zaman. CI'dan tetiklenen düz rsync over SSH, şaşırtıcı sayıda gerçek deployment'ı kapsıyor:

deploy_staging:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client rsync
    - eval $(ssh-agent -s)
    - echo "$STAGING_SSH_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh && chmod 700 ~/.ssh
    - ssh-keyscan -H "$STAGING_HOST" >> ~/.ssh/known_hosts
  script:
    - rsync -az --delete dist/ deploy@$STAGING_HOST:/var/www/staging/
  environment:
    name: staging
    url: https://staging.example.com
  rules:
    - if: '$CI_COMMIT_BRANCH == "develop"'

SSH key'i repo'da asla yaşamıyor, maskelenmiş, protected bir CI/CD variable'ında tutuluyor. ssh-keyscan, known_hosts'u dolduruyor, böylece job bir host-key prompt'unda asılı kalmıyor, ve rsync --delete, yavaşça eski dosya biriktirmek yerine, remote dizini build çıktısıyla senkron tutuyor.

Production'a manuel bir kapı

Staging, develop'a her push'ta deploy oluyor. Production, main'den deploy oluyor, ama sadece biri butona bastığında:

deploy_production:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client rsync
    - eval $(ssh-agent -s)
    - echo "$PRODUCTION_SSH_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh && chmod 700 ~/.ssh
    - ssh-keyscan -H "$PRODUCTION_HOST" >> ~/.ssh/known_hosts
  script:
    - rsync -az --delete dist/ deploy@$PRODUCTION_HOST:/var/www/production/
  environment:
    name: production
    url: https://example.com
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
  when: manual

when: manual, job'ı otomatik tetiklenen bir şey olmaktan çıkarıp GitLab'ın pipeline görünümünde bir butona çeviriyor. GitLab'ın environment'larıyla birlikte, bu aynı zamanda önceki bir artifact'e tek tıkla rollback yapabileceğiniz bir deploy history veriyor, ve bu birden fazla kez kötü bir deploy'u panikten otuz saniyelik bir düzeltmeye çevirdi.

Neden genelde bu yeterli

Bu pipeline bir linter çalıştırmıyor, bir Docker image build etmiyor, Kubernetes'le konuşmuyor. Birçok küçük proje için bu sorun değil, proje büyüyüp ihtiyaç duyarsa bunlar sonra eklenebilir. Bu pipeline'ın yaptığı, manuel deploy'ların ters gittiği üç noktayı ortadan kaldırmak: biri dependency kurmayı unutuyor, biri test edilmemiş kod deploy ediyor, ya da biri yanlış branch'i deploy ediyor. Bu boyuttaki bir .gitlab-ci.yml üçünü de yakalıyor, ve projeye dokunacak bir sonraki kişinin bir dakikadan kısa sürede tamamını okuyabileceği kadar kısa.

ÖncekiHer Yeni Sunucuda Tekrar Kullandığım Bash Script'leriSonraki Her Yeni Sunucuda Çalıştırdığım Ansible Playbook'u