📖 Docker & DevOps - CI/CD Pipelines với GitHub Actions
70 phút

CI/CD Pipelines với GitHub Actions

Giới thiệu CI/CD

CI/CD (Continuous Integration/Continuous Deployment) là practice tự động hóa quá trình build, test và deploy ứng dụng.

GitHub Actions Basics

Workflow Structure

name: CI/CD Pipeline

on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run tests
      run: npm test
    
    - name: Build application
      run: npm run build

Environment Variables và Secrets

env:
  NODE_ENV: production
  REGISTRY: ghcr.io

jobs:
  deploy:
    environment: production
    steps:
    - name: Deploy to production
      run: echo "Deploying..."
      env:
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
        API_KEY: ${{ secrets.API_KEY }}

Advanced CI/CD Patterns

Matrix Builds

jobs:
  test:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        node-version: [16, 18, 20]
        os: [ubuntu-latest, windows-latest]
    steps:
    - uses: actions/checkout@v3
    - name: Use Node.js ${{ matrix.node-version }} on ${{ matrix.os }}
      uses: actions/setup-node@v3
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'

Caching

- name: Cache node modules
  uses: actions/cache@v3
  with:
    path: ~/.npm
    key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
    restore-keys: |
      ${{ runner.os }}-node-

Deployment Strategies

Blue-Green Deployment

deploy-blue:
  runs-on: ubuntu-latest
  steps:
  - name: Deploy to blue environment
    run: |
      kubectl apply -f deployment-blue.yaml
      kubectl rollout status deployment/my-app-blue

  - name: Test blue deployment
    run: |
      # Run smoke tests
      curl -f http://blue.myapp.com/health

  - name: Switch traffic to blue
    run: |
      kubectl apply -f service-blue.yaml

Canary Deployment

deploy-canary:
  runs-on: ubuntu-latest
  steps:
  - name: Deploy canary
    run: |
      kubectl apply -f deployment-canary.yaml
      # Start with 10% traffic
      kubectl set traffic deployment/my-app --weight=90,10

  - name: Monitor canary
    run: |
      # Monitor metrics for 15 minutes
      sleep 900
      # Check error rate and performance

  - name: Rollout to 100%
    if: success()
    run: |
      kubectl set traffic deployment/my-app --weight=0,100
      kubectl delete deployment/my-app-canary

Security Scanning

Code Security

security-scan:
  runs-on: ubuntu-latest
  steps:
  - uses: actions/checkout@v3
  
  - name: Run SAST
    uses: github/codeql-action/analyze@v2
    with:
      languages: javascript
  
  - name: Dependency vulnerability scan
    run: npm audit --audit-level moderate
  
  - name: Run Snyk security scan
    uses: snyk/actions/node@master
    env:
      SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

Container Security

container-scan:
  runs-on: ubuntu-latest
  steps:
  - name: Build container
    run: docker build -t my-app:${{ github.sha }} .
  
  - name: Scan container
    uses: aquasecurity/trivy-action@master
    with:
      image-ref: 'my-app:${{ github.sha }}'
      format: 'sarif'
      output: 'trivy-results.sarif'
  
  - name: Upload scan results
    uses: github/codeql-action/upload-sarif@v2
    with:
      sarif_file: 'trivy-results.sarif'

Monitoring và Notifications

Slack Notifications

- name: Notify Slack
  uses: 8398a7/action-slack@v3
  with:
    status: ${{ job.status }}
    channel: '#deployments'
    text: 'Deployment ${{ job.status }} for ${{ github.ref }}'
  env:
    SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
  if: always()

Status Checks

health-check:
  runs-on: ubuntu-latest
  needs: deploy
  steps:
  - name: Wait for deployment
    run: sleep 30
  
  - name: Health check
    run: |
      response=$(curl -s -o /dev/null -w "%{http_code}" https://myapp.com/health)
      if [ $response -ne 200 ]; then
        echo "Health check failed"
        exit 1
      fi

📝 Bài tập (1)

  1. Tạo complete CI/CD pipeline từ code đến production

Bài học "CI/CD Pipelines với GitHub Actions" - Khóa học "Docker & DevOps"