CI/CD Pipeline Best Practices: A Practical Guide for 2025
Service: SEO-Optimized Blog Post | Price: $15 | Format: dev.to-ready | Category: DevOps
Modern CI/CD pipelines are the backbone of software delivery. A well-architected pipeline catches bugs early, deploys with confidence, and keeps your team shipping fast. A poorly designed one becomes a bottleneck that everyone dreads.
This guide covers battle-tested patterns for building pipelines that scale — from small side projects to production monorepos.
1. Pipeline Architecture Patterns
The Three-Stage Pipeline
Every pipeline should have three clear stages:
# Minimal three-stage pipeline
name: CI/CD
on: [push, pull_request]
jobs:
verify: # Lint, typecheck, unit tests
build: # Build artifacts, run integration tests
deploy: # Deploy to environment (gated on main branch)
Why three stages?
- Verify fails fast (under 2 minutes)
- Build validates integration (under 5 minutes)
- Deploy requires human approval for production
Monorepo Optimization
Monorepos need smart change detection:
# Path-based filtering for monorepos
jobs:
api-tests:
if: contains(github.event.head_commit.modified, 'packages/api/')
runs-on: ubuntu-latest
ui-tests:
if: contains(github.event.head_commit.modified, 'packages/ui/')
2. Speed Optimization
Parallel Job Execution
Run independent jobs in parallel instead of sequential stages:
jobs:
lint:
typecheck:
unit-tests:
# All three run simultaneously
Docker Layer Caching
Speed up Docker builds by 70%:
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ hashFiles('**/Dockerfile') }}
Dependency Cache
Never re-download unchanged dependencies:
- name: Cache pnpm
uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }}
3. Testing Strategy
Fail Fast, Fail Early
Run the fastest checks first:
- TypeScript typecheck (10s)
- Unit tests (30s)
- Integration tests (2min)
- E2E tests (10min)
Test Matrix Against Real Environments
strategy:
matrix:
node-version: [18, 20, 22]
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
4. Deployment Safety
Environment Gates
deploy-staging:
needs: [lint, typecheck, unit-tests]
environment: staging
deploy-production:
needs: [deploy-staging]
environment: production
if: github.ref == 'refs/heads/main'
Zero-Downtime Deployments
- name: Deploy with health check
run: |
docker compose up -d --wait --wait-timeout 60
curl --retry 5 --retry-delay 5 http://localhost:3100/api/health
Rollback Automation
- name: Rollback on failure
if: failure()
run: |
docker compose down
docker compose -f docker-compose.previous.yml up -d
5. Real-World Configurations
Full GitHub Actions CI Pipeline
name: CI
on:
push:
branches: [main]
pull_request:
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20, cache: pnpm }
- run: pnpm install --frozen-lockfile
- run: pnpm typecheck
- run: pnpm lint
- run: pnpm test
build:
needs: verify
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: pnpm install --frozen-lockfile
- run: pnpm build
docker:
needs: build
runs-on: ubuntu-latest
steps:
- uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
GitLab CI Pipeline
stages:
- verify
- build
- deploy
verify:test:
stage: verify
script:
- npm ci
- npm run typecheck
- npm run test
cache:
key: $CI_COMMIT_REF_SLUG
paths:
- node_modules/
Key Takeaways
- Three-stage architecture — Verify → Build → Deploy
- Parallel execution — Independent jobs run simultaneously
- Layer caching — Cut Docker build times by 70%
- Environment gates — Never deploy untested code to production
- Health checks — Always verify the deployment actually works
This post is part of the Production DevOps Patterns series. Follow for more DevOps, CI/CD, and infrastructure best practices.
Publish-ready: Copy this markdown directly to dev.to, Medium, or your blog. Frontmatter included.
Top comments (0)