DevOps

Introduction to CI/CD Pipelines

Dinesh SutiharFebruary 1, 202613 min read
DevOpsCI/CDGitHub ActionsDocker
Introduction to CI/CD Pipelines

What is CI/CD?

CI/CD stands for Continuous Integration and Continuous Deployment. CI automates building and testing code changes, while CD automates the deployment process. Together, they form a pipeline that ensures code changes are reliable and can be released quickly.

  • Continuous Integration: Merge code frequently, run automated tests
  • Continuous Delivery: Keep code deployable at any time
  • Continuous Deployment: Automatically deploy every change that passes tests

GitHub Actions Basics

GitHub Actions is a powerful CI/CD platform built into GitHub. Workflows are defined in YAML files in the .github/workflows directory.

yaml
# .github/workflows/ci.yml
name:CI Pipeline
 
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
 
jobs:
test:
runs-on: ubuntu-latest
steps:
- name:Checkout code
uses: actions/checkout@v4
- name:Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- name:Install dependencies
run: npm ci
- name:Run linter
run: npm run lint
- name:Run tests
run: npm test
- name:Build application
run: npm run build

Docker in CI/CD

Docker ensures consistent environments from development to production. Here's how to build and push Docker images in your pipeline:

yaml
# Build and push Docker image
build:
needs: test
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:
context: .
push: true
tags: |
myapp:latest
myapp:${{ github.sha }}

Sample Dockerfile

dockerfile
# Multi-stage build for smaller image
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
 
FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
 
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/package.json ./
 
EXPOSE 3000
CMD ["node", "dist/index.js"]

Environment Management

yaml
# Deploy to different environments
deploy-staging:
needs: build
runs-on: ubuntu-latest
environment: staging
steps:
- name:Deploy to staging
run: |
echo "Deploying to staging..."
# Add your deployment commands here
deploy-production:
needs: deploy-staging
runs-on: ubuntu-latest
environment: production
if: github.ref == 'refs/heads/main'
steps:
- name:Deploy to production
run: |
echo "Deploying to production..."

Deployment Strategies

  • Rolling Update: Gradually replace old instances with new ones
  • Blue-Green: Run two identical environments, switch traffic instantly
  • Canary: Route small percentage of traffic to new version first
  • Feature Flags: Deploy code but enable features selectively

Best Practices

  • Keep pipelines fast - cache dependencies, parallelize jobs
  • Use branch protection rules to require passing checks
  • Store secrets securely using GitHub Secrets or vault
  • Version your Docker images with commit SHA
  • Implement rollback mechanisms for failed deployments
  • Monitor deployments and set up alerts
  • Document your pipeline in the repository
If it hurts, do it more frequently, and bring the pain forward. - Continuous Delivery principle

Conclusion

CI/CD pipelines are essential for modern software development. Start with a simple workflow that runs tests on every push, then gradually add build, security scanning, and deployment stages. The goal is to make releasing software boring - and that's a good thing.

Share this article