CI/CD — GitHub Actions bilan avtomatik deploy

~20 daq · NestJS · Deployment

Muammodan boshlaylik

Har safar yangi feature yozganingizda:

1. git push
2. SSH bilan serverga kirish
3. git pull
4. npm install
5. npm run build
6. pm2 restart

Bu takroriy, zerikarli va xato qilish oson. Biror qadam unutilsa — server ishlamay qoladi.

CI/CD bu jarayonni avtomatlashtiradi: siz faqat git push qilasiz — qolganini tizim o'zi qiladi.


CI/CD nima?

CI (Continuous Integration) — har commit da testlar va build ishga tushadi. CD (Continuous Deployment) — testlar o'tsa, avtomatik serverga deploy qilinadi.

Hayotiy o'xshatma: avtomobil konveyer.

Zavod ishchisi bitta operatsiya qiladi — qolganini konveyer o'zi bajaradi. Xato bo'lsa — konveyer to'xtaydi, xato tuzatilib qaytadan ishga tushiriladi.


GitHub Actions

GitHub Actions — GitHub dagi bepul CI/CD tizimi. .github/workflows/ papkasida YAML fayllar yoziladi.

git push → GitHub Actions ishga tushdi:
  1. Kod tekshiruvi (lint)
  2. Testlar
  3. Build
  4. Serverga deploy

Asosiy workflow

# .github/workflows/deploy.yml

name: Deploy

on:
  push:
    branches: [main]          # main ga push bo'lganda

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      # 1. Kodni olish
      - name: Checkout
        uses: actions/checkout@v4

      # 2. Node.js o'rnatish
      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: 'npm'

      # 3. Paketlarni o'rnatish
      - name: Install dependencies
        run: npm ci

      # 4. Build qilish
      - name: Build
        run: npm run build

      # 5. Serverga deploy
      - name: Deploy to server
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/myapp
            git pull origin main
            npm ci --only=production
            npm run build
            pm2 restart myapp

Testlar bilan

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - run: npm ci
      - run: npm test

  deploy:
    needs: test           # ← testlar o'tgandan keyin deploy
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/myapp
            git pull
            npm ci --only=production
            npm run build
            pm2 restart myapp

Secrets sozlash

GitHub repo → Settings → Secrets and variables → Actions:

SERVER_HOST      → 123.45.67.89
SERVER_USER      → ubuntu
SSH_PRIVATE_KEY  → -----BEGIN OPENSSH PRIVATE KEY-----...

⚠️ Secrets YAML faylda ko'rinmaydi — GitHub ularni log da ham yashiradi.


SSH kaliti yaratish

# Lokal mashinada
ssh-keygen -t ed25519 -C "github-actions"
# → ~/.ssh/id_ed25519 (private key)
# → ~/.ssh/id_ed25519.pub (public key)

# Public keyni serverga qo'shish
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys

# Private keyni GitHub Secrets ga qo'shing
cat ~/.ssh/id_ed25519

Docker bilan deploy

Agar Docker ishlatilsa:

steps:
  - uses: actions/checkout@v4

  # Docker Hub ga login
  - name: Login to Docker Hub
    uses: docker/login-action@v3
    with:
      username: ${{ secrets.DOCKER_USERNAME }}
      password: ${{ secrets.DOCKER_PASSWORD }}

  # Image yaratish va push
  - name: Build and push
    uses: docker/build-push-action@v5
    with:
      push: true
      tags: yourusername/myapp:latest

  # Serverga yangi imageni pull qilish
  - name: Deploy
    uses: appleboy/ssh-action@master
    with:
      host: ${{ secrets.SERVER_HOST }}
      username: ${{ secrets.SERVER_USER }}
      key: ${{ secrets.SSH_PRIVATE_KEY }}
      script: |
        docker pull yourusername/myapp:latest
        docker compose up -d

Tez-tez uchraydigan xatolar

1. SSH ulanish xatosi

Error: dial tcp: connect: connection refused

Sababi: Public key serverda authorized_keys ga qo'shilmagan. Yechim: cat id_ed25519.pub >> ~/.ssh/authorized_keys qayta bajarib tekshiring.


2. Build muvaffaqiyatli, lekin eski kod ishlayapti Sababi: pm2 restart eski dist ni ishlatmoqda. Yechim: npm run build dan keyin pm2 reload myapp (zero-downtime restart).


3. Secrets noto'g'ri

Error: Host key verification failed

Yechim: Secrets dagi qiymatlarni tekshiring, bo'shliq yoki yangi qator qolmaganiga ishonch hosil qiling.


Xulosa

Eslab qoling:

  • CI/CD — git push dan keyingi jarayonni avtomatlashtiradi
  • GitHub Actions — .github/workflows/ da YAML fayllar
  • secrets — parollar, SSH kalitlar xavfsiz saqlanadi
  • needs — joblar tartibini belgilaydi
  • Testlar o'tmasa — deploy qilinmaydi

Keyingi dars: 60-dars: VPS — server sozlash, PM2, deploy qilish