Linux Otomatik Deployment: CI/CD Pipeline Rehberi

CI/CD (Continuous Integration/Continuous Deployment), kod değişikliklerinin otomatik test edilmesi ve canlı ortama dağıtılması sürecidir. Manuel...

Linux
Linux Otomatik Deployment: CI/CD Pipeline Rehberi

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
Celil Uyanikoglu

Yazan Celil Uyanikoglu

25 yıldır bilgi işlem piyasasında farklı dallarda uzmanlaşan bir Bilgisayar Mühendisi

Yorum

Henüz yorum yok.

Sohbete katıl. Yorumlar yayınlanmadan önce moderasyondan geçer.

Yorum yap

E-posta adresin yayınlanmaz. Yorumlar moderasyondan sonra yayınlanır.

Sırada

İlgili notlar