CI/CD (Continuous Integration/Continuous Deployment), kod değişikliklerinin otomatik test edilmesi ve canlı ortama dağıtılması sürecidir. Manuel dağıtım hatalarını azaltır, sürüm döngüsünü hızlandırır. CI/CD Nedir?
Continuous Integration (CI): Kod değişiklikleri sürekli olarak ana dalda birleştirilir ve otomatik testlerden geçirilir.
Continuous Deployment (CD): Testleri geçen kod otomatik olarak canlı ortama dağıtılır.
Faydaları:
- Hızlı geri bildirim
- Daha az manuel hata
- Sık ve güvenli sürümler
- Tutarlı dağıtım süreci
CI/CD Araçları
GitHub Actions
GitHub'a entegre bulut tabanlı CI/CD platformu. YAML dosyaları ile tanımlanır. Açık kaynak projeler için ücretsiz.
Avantajları: Kolay kurulum, GitHub entegrasyonu, geniş marketplace. Dezavantajları: Sadece GitHub repoları için çalışır.
GitLab CI
GitLab'ın entegre DevOps platformu. .gitlab-ci.yml dosyası ile yapılandırılır. Güvenlik taraması, uyumluluk kontrolleri dahili.
Avantajları: All-in-one DevSecOps, self-hosted seçeneği. Dezavantajları: GitLab ekosistemi dışında kullanım zor.
Jenkins
Açık kaynak, self-hosted CI/CD sunucusu. 1800+ eklenti ile son derece özelleştirilebilir. Kurumsal ortamlarda yaygın.
Avantajları: Maksimum esneklik, on-premise çalışır. Dezavantajları: Kurulum ve bakım gerektirir, güvenlik güncellemeleri kritik.
GitHub Actions ile Deployment
Temel Yapılandırma
Repo kökünde .github/workflows/deploy.yml dosyası oluşturun:
name: Deploy to Production
on: push: branches: [main]
jobs: deploy: runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- name: Setup Node.js uses: actions/setup-node@v4 with: node-version: '20'
- name: Install dependencies run: npm ci
- name: Run tests run: npm test
- name: Build run: npm run build
- name: Deploy to server uses: appleboy/[email protected] with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.SSH_KEY }} script: | cd /var/www/app git pull origin main npm ci --production pm2 restart app
Secrets Ayarlama
GitHub repo ayarlarında Settings > Secrets and variables > Actions:
HOST: Sunucu IP adresi USERNAME: SSH kullanıcı adı SSH_KEY: Özel SSH anahtarı
SSH Anahtarı Oluşturma
ssh-keygen -t ed25519 -C "deploy@github-actions"
Özel anahtarı GitHub secrets'a, genel anahtarı sunucunun ~/.ssh/authorized_keys dosyasına ekleyin.
GitLab CI ile Deployment
Temel Yapılandırma
Repo kökünde .gitlab-ci.yml dosyası:
stages:
- test
- build
- deploy
variables: NODE_VERSION: "20"
test: stage: test image: node:${NODE_VERSION} script:
- npm ci
- npm test
build: stage: build image: node:${NODE_VERSION} script: - npm ci - npm run build artifacts: paths: - dist/
deploy: stage: deploy image: alpine:latest only: - main before_script: - apk add --no-cache openssh-client - eval $(ssh-agent -s) - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - - mkdir -p ~/.ssh - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts script: - scp -r dist/* $DEPLOY_USER@$DEPLOY_HOST:/var/www/app/ - ssh $DEPLOY_USER@$DEPLOY_HOST "cd /var/www/app && pm2 restart app"
Variables Ayarlama
GitLab'da Settings > CI/CD > Variables:
SSH_PRIVATE_KEY: Özel SSH anahtarı SSH_KNOWN_HOSTS: ssh-keyscan sunucu çıktısı DEPLOY_HOST: Sunucu adresi DEPLOY_USER: SSH kullanıcısı
Jenkins ile Deployment
Jenkins Kurulumu
wget -q -O - https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo apt-key add - sudo sh -c 'echo deb https://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' sudo apt update sudo apt install jenkins sudo systemctl enable --now jenkins
Tarayıcıdan http://sunucu:8080 adresinde kurulumu tamamlayın.
Pipeline Yapılandırması (Jenkinsfile)
Repo kökünde Jenkinsfile:
pipeline { agent any
environment { NODE_VERSION = '20' }
stages { stage('Checkout') { steps { checkout scm } }
stage('Install') { steps { sh 'npm ci' } }
stage('Test') { steps { sh 'npm test' } }
stage('Build') { steps { sh 'npm run build' } }
stage('Deploy') { when { branch 'main' } steps { sshagent(['deploy-key']) { sh ''' scp -r dist/* deploy@sunucu:/var/www/app/ ssh deploy@sunucu "cd /var/www/app && pm2 restart app" ''' } } } }
post { failure { mail to: '[email protected]', subject: "Pipeline Failed: ${currentBuild.fullDisplayName}", body: "Check: ${env.BUILD_URL}" } } }
Basit Deployment Script
CI/CD platformundan bağımsız deployment scripti:
/home/deploy/deploy.sh:
#!/bin/bash set -e
APP_DIR="/var/www/app" REPO="[email protected]:user/app.git" BRANCH="main"
cd $APP_DIR
# Pull latest changes git fetch origin git reset --hard origin/$BRANCH
# Install dependencies npm ci --production
# Build if needed if [ -f "package.json" ] && grep -q '"build"' package.json; then npm run build fi
# Restart application pm2 restart app || pm2 start ecosystem.config.js
# Clean up npm cache clean --force
echo "Deployment completed at $(date)"
Webhook ile Tetikleme
GitHub webhook ayarlayarak push'ta otomatik deploy:
Sunucuda basit webhook listener:
#!/bin/bash # /home/deploy/webhook.sh while true; do nc -l -p 9000 -c '/home/deploy/deploy.sh >> /var/log/deploy.log 2>&1' done
Daha güvenli çözüm için webhook veya adnanh/webhook kullanın.
Docker ile Deployment
Dockerfile
FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build
FROM node:20-alpine WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules COPY package*.json ./ EXPOSE 3000 CMD ["node", "dist/server.js"]
GitHub Actions ile Docker
name: Docker Deploy
on: push: branches: [main]
jobs: build-and-deploy: runs-on: ubuntu-latest steps:
- uses: actions/checkout@v4
- name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_TOKEN }}
- name: Build and push uses: docker/build-push-action@v5 with: push: true tags: user/app:latest
- name: Deploy uses: appleboy/[email protected] with: host: ${{ secrets.HOST }} username: ${{ secrets.USERNAME }} key: ${{ secrets.SSH_KEY }} script: | docker pull user/app:latest docker stop app || true docker rm app || true docker run -d --name app -p 3000:3000 user/app:latest
Zero-Downtime Deployment
Rolling Update
pm2 ile zero-downtime:
pm2 reload app
Blue-Green Deployment
İki ortam arasında geçiş:
# Blue aktif, Green'e deploy et rsync -avz dist/ /var/www/green/
# Test et curl -f http://localhost:3001/health
# Nginx'i Green'e yönlendir sudo ln -sf /etc/nginx/sites-available/green /etc/nginx/sites-enabled/app sudo nginx -s reload
Güvenlik İpuçları
Secrets yönetimi: Şifreleri asla koda yazmayın. CI/CD platformunun secrets özelliğini kullanın.
Minimum yetki: Deploy kullanıcısına sadece gerekli izinleri verin.
SSH key rotation: Anahtarları periyodik olarak değiştirin.
Audit log: Deployment geçmişini kaydedin.
Rollback planı: Sorun çıktığında önceki sürüme dönme stratejisi hazırlayın.
Sorun Giderme
SSH bağlantı hatası:
- Anahtarın doğru formatta olduğunu kontrol edin
- known_hosts doğru mu kontrol edin
- Sunucuda SSH port ve firewall kontrol edin
İzin hatası:
- Deploy kullanıcısının dizin yazma yetkisi var mı
- Dosya sahipliğini kontrol edin
Build hatası:
- Node/npm versiyonları uyumlu mu
- Dependencies güncel mi
Henüz yorum yok.
Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.