Back to DevOps

CI/CD Tutorial

Master CI/CD fundamentals with our comprehensive tutorial. Learn continuous integration, deployment automation, and pipeline best practices.

Video Tutorial

Introduction to CI/CD

CI/CD (Continuous Integration/Continuous Deployment) is a method to frequently deliver apps to customers by introducing automation into the stages of app development. It helps teams deliver code changes more frequently and reliably.

Examples:

# CI/CD Pipeline Stages
1. Source - Code repository (Git)
2. Build - Compile and package code
3. Test - Run automated tests
4. Deploy - Deploy to environments
5. Monitor - Track application health

The typical stages of a CI/CD pipeline

GitHub Actions Basics

GitHub Actions is a CI/CD platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository.

Examples:

name: CI Pipeline

on:
  push:
    branches: [ main ]
  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'
    
    - name: Install dependencies
      run: npm install
    
    - name: Run tests
      run: npm test
    
    - name: Build
      run: npm run build

A basic GitHub Actions workflow for Node.js on: Trigger events jobs: Define jobs to run steps: Individual tasks in a job

Docker Build and Push

Automate building and pushing Docker images to a container registry as part of your CI/CD pipeline.

Examples:

name: Docker Build and Push

on:
  push:
    branches: [ main ]

jobs:
  docker:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
    
    - name: Login to Docker Hub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKER_USERNAME }}
        password: ${{ secrets.DOCKER_PASSWORD }}
    
    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        context: .
        push: true
        tags: user/app:latest

Build and push Docker images to Docker Hub secrets: Store credentials securely tags: Version your images

Automated Testing

Automated testing is crucial in CI/CD pipelines. It ensures code quality and catches bugs early in the development process.

Examples:

name: Test Suite

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
    
    - name: Install dependencies
      run: npm ci
    
    - name: Run unit tests
      run: npm run test:unit
    
    - name: Run integration tests
      run: npm run test:integration
    
    - name: Generate coverage report
      run: npm run test:coverage
    
    - name: Upload coverage
      uses: codecov/codecov-action@v3

Comprehensive testing workflow npm ci: Clean install for CI Coverage: Track test coverage

Deployment Strategies

Different deployment strategies help minimize downtime and risk when releasing new versions of your application.

Examples:

name: Deploy to Production

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: production
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy to server
      uses: appleboy/ssh-action@master
      with:
        host: ${{ secrets.HOST }}
        username: ${{ secrets.USERNAME }}
        key: ${{ secrets.SSH_KEY }}
        script: |
          cd /var/www/app
          git pull origin main
          npm install
          npm run build
          pm2 restart app

Deploy to production server via SSH environment: Deployment environment SSH: Secure remote execution

# Blue-Green Deployment Strategy
1. Deploy new version (Green)
2. Test Green environment
3. Switch traffic to Green
4. Keep Blue as backup
5. Decommission Blue after validation

Blue-Green deployment minimizes downtime

Jenkins Pipeline

Jenkins is a popular open-source automation server. It helps automate the parts of software development related to building, testing, and deploying.

Examples:

pipeline {
    agent any
    
    stages {
        stage('Build') {
            steps {
                sh 'npm install'
                sh 'npm run build'
            }
        }
        
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
        
        stage('Deploy') {
            steps {
                sh 'docker build -t myapp .'
                sh 'docker push myapp:latest'
            }
        }
    }
    
    post {
        success {
            echo 'Pipeline succeeded!'
        }
        failure {
            echo 'Pipeline failed!'
        }
    }
}

Jenkins declarative pipeline stages: Pipeline stages post: Actions after pipeline completion

Environment Variables and Secrets

Managing environment variables and secrets securely is critical in CI/CD pipelines to protect sensitive information.

Examples:

name: Deploy with Secrets

on:
  push:
    branches: [ main ]

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy
      env:
        API_KEY: ${{ secrets.API_KEY }}
        DATABASE_URL: ${{ secrets.DATABASE_URL }}
        NODE_ENV: production
      run: |
        echo "Deploying with environment variables"
        npm run deploy

Using secrets in workflows secrets: Encrypted environment variables env: Set environment variables

# Setting secrets in GitHub
# Repository Settings > Secrets and variables > Actions
# Click 'New repository secret'
# Add: API_KEY, DATABASE_URL, etc.

How to add secrets in GitHub repository settings

Monitoring and Notifications

Monitor your CI/CD pipelines and get notified when builds fail or succeed to maintain code quality and quick response times.

Examples:

name: Build with Notifications

on: [push, pull_request]

jobs:
  build:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Build
      run: npm run build
    
    - name: Notify on success
      if: success()
      uses: 8398a7/action-slack@v3
      with:
        status: success
        text: 'Build succeeded!'
        webhook_url: ${{ secrets.SLACK_WEBHOOK }}
    
    - name: Notify on failure
      if: failure()
      uses: 8398a7/action-slack@v3
      with:
        status: failure
        text: 'Build failed!'
        webhook_url: ${{ secrets.SLACK_WEBHOOK }}

Send notifications to Slack if: Conditional execution webhook: Integration endpoint

Quick Reference

Key Concepts

  • • Continuous Integration (CI)
  • • Continuous Deployment (CD)
  • • Automated Testing
  • • Pipeline as Code

Best Practices

  • ✓ Commit code frequently
  • ✓ Automate everything
  • ✓ Test in production-like env
  • ✓ Monitor pipeline metrics