Setting up a CI/CD pipeline is not about picking a tool and writing a YAML file. It is about designing a reliable, fast, and secure delivery system that your team will actually trust. This guide walks through the entire process — from tool selection to production monitoring.
Read also: Kubernetes Implementation Checklist for Production | Cloud Migration Checklist: Step-by-Step Guide
Step 1: Choose the right CI/CD tool
The tool you pick determines your constraints for the next 3-5 years. Choose based on your actual requirements, not popularity.
Decision matrix
| Criteria | Jenkins | GitHub Actions | GitLab CI |
|---|---|---|---|
| Infrastructure | Self-hosted (you manage servers) | Cloud-managed (GitHub hosts runners) | Cloud-managed or self-hosted |
| Setup time | Days to weeks | Minutes to hours | Hours to a day |
| Plugin ecosystem | 1,800+ plugins (variable quality) | 20,000+ marketplace actions | Built-in features, fewer extensions |
| Pipeline as code | Jenkinsfile (Groovy) | YAML workflows | .gitlab-ci.yml (YAML) |
| Container registry | Requires plugin | GitHub Packages (built-in) | Built-in registry |
| Security scanning | Plugins required | Third-party actions | Built-in SAST, DAST, dependency scanning |
| Cost (small team) | Server costs ($50-200/month) | 2,000 free minutes/month | 400 free minutes/month |
| Best for | Complex enterprise pipelines | GitHub-native projects | All-in-one DevOps platform |
When to pick each tool
GitHub Actions — your code is on GitHub, you want fast setup, and you prefer managed infrastructure. Best for teams of 2-50 developers.
GitLab CI — you want source code management, CI/CD, container registry, and security scanning in one platform. Best for organizations that want to consolidate tools.
Jenkins — you have existing Jenkins infrastructure, complex multi-branch pipelines with custom logic, or hard requirements for on-premises execution. Be aware that Jenkins requires ongoing maintenance — someone must manage the server, update plugins, and handle scaling.
Step 2: Design the pipeline architecture
Before writing configuration files, define what your pipeline needs to do.
Pipeline stages (in order)
- Source — trigger on push, pull request, or tag
- Build — compile code, build containers, generate artifacts
- Unit tests — fast tests that run in seconds, no external dependencies
- Integration tests — tests against real databases, APIs, or message queues
- Security scan — SAST (code), SCA (dependencies), container image scanning
- Artifact publish — push container images or packages to registry
- Deploy to staging — automatic deployment to pre-production environment
- Acceptance tests — end-to-end tests against staging
- Deploy to production — manual approval gate or automatic with canary
- Post-deploy validation — smoke tests, health checks, metric comparison
Speed targets
| Stage | Target duration | If slower, consider |
|---|---|---|
| Build | Under 3 minutes | Multi-stage Docker builds, layer caching |
| Unit tests | Under 5 minutes | Parallel test execution, test splitting |
| Integration tests | Under 10 minutes | Testcontainers, parallel suites |
| Security scan | Under 5 minutes | Incremental scans, baseline suppression |
| Full pipeline | Under 20 minutes | Parallelize independent stages |
A pipeline that takes over 30 minutes will be bypassed by developers. Speed is not optional.
Step 3: Set up the build stage
Container build best practices
Use multi-stage builds to keep final images small and secure:
# Build stage
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --production=false
COPY . .
RUN npm run build
# Production stage
FROM node:20-alpine AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
EXPOSE 3000
CMD ["node", "dist/main.js"]
Build caching
Caching reduces build times by 50-80%. Configure it per tool:
- GitHub Actions:
actions/cachefor dependencies, Docker layer caching withdocker/build-push-action - GitLab CI:
cache:directive for dependencies, kaniko cache for container builds - Jenkins: persistent workspace volumes, Docker BuildKit cache mounts
Artifact versioning
Tag every artifact with a unique, traceable version:
- Format:
{service}-{semver}-{short-sha}(e.g.,api-1.4.2-a3f9b21) - Never use
latestin production — it is not reproducible - Store build metadata: commit SHA, branch, build number, build timestamp
Step 4: Integrate testing
Test pyramid in CI/CD
| Layer | Count | Speed | Runs on |
|---|---|---|---|
| Unit tests | Hundreds to thousands | Milliseconds each | Every commit |
| Integration tests | Dozens to hundreds | Seconds each | Every commit |
| E2E tests | 10-50 critical paths | Minutes each | Pre-deploy to staging |
| Performance tests | 3-5 scenarios | Minutes | Nightly or pre-release |
Parallel test execution
Split tests across multiple runners to cut execution time:
- GitHub Actions: use a matrix strategy to run test suites in parallel
- GitLab CI: use
parallel:keyword with test splitting - All tools: split by test file, module, or timing data (slowest tests first)
Quality gates
Define gates that block deployments:
- All unit and integration tests pass (zero tolerance)
- Code coverage does not drop below baseline (e.g., 80%)
- No critical or high vulnerabilities in security scan
- No lint errors
- Performance benchmarks within 10% of baseline
Step 5: Choose a deployment strategy
Rolling update (default)
Replace instances one at a time. Simple, no extra infrastructure. Risk: both old and new versions serve traffic simultaneously during rollout.
Best for: internal services, APIs with backward-compatible changes.
Blue-green deployment
Run two identical environments. Deploy to the idle one, validate, switch traffic.
Best for: applications where you need instant rollback and can afford double infrastructure during deployment.
Canary deployment
Route 1-5% of traffic to the new version. Monitor error rates and latency. Gradually increase to 100%.
Best for: high-traffic user-facing applications where you want to limit blast radius.
Implementation checklist
- Choose strategy per service (not one strategy for everything)
- Configure health checks: liveness, readiness, and startup probes
- Define rollback triggers: error rate exceeds 1%, p99 latency exceeds 2x baseline, health check failures
- Automate rollback — do not rely on a human watching dashboards at 3 AM
- Test rollback procedure monthly
Step 6: Set up monitoring and alerts
Pipeline monitoring
Track these metrics for every pipeline:
- Build frequency: how often the pipeline runs (target: multiple times per day)
- Build duration: total pipeline time (target: under 20 minutes)
- Build success rate: percentage of green builds (target: above 95%)
- Mean time to recovery: how fast you fix a broken build (target: under 1 hour)
- Deployment frequency: how often you deploy to production (target: daily or more)
Production monitoring post-deploy
After every deployment, automatically verify:
- Health check endpoints return 200
- Error rate has not increased compared to pre-deploy baseline
- Response latency (p50, p95, p99) is within expected range
- No increase in exception count in error tracking (Sentry, Bugsnag)
- Key business metrics are not degraded (conversion rate, transaction volume)
Alerting rules
| Condition | Severity | Action |
|---|---|---|
| Build broken on main branch | Critical | Notify team immediately (Slack, PagerDuty) |
| Pipeline duration exceeds 30 minutes | Warning | Investigate caching and parallelization |
| Deployment failure | Critical | Auto-rollback, notify on-call |
| Post-deploy error rate above 1% | Critical | Auto-rollback, page on-call engineer |
| Security scan finds critical CVE | High | Block deployment, create ticket |
Common mistakes and how to avoid them
| Mistake | Impact | Fix |
|---|---|---|
| No caching | 20-minute builds that should take 5 minutes | Cache dependencies and Docker layers from day one |
| Tests depend on shared state | Flaky tests that erode trust in the pipeline | Isolate tests — each test creates and cleans its own data |
| Secrets in pipeline config | Credentials exposed in logs or repo history | Use secret management (GitHub Secrets, GitLab CI Variables, Vault) |
| No deployment approval for production | Accidental production deployments | Require manual approval gate before production deploy |
| Ignoring pipeline metrics | Slow pipelines, frequent failures, nobody notices | Dashboard with build duration, success rate, deployment frequency |
| Monolithic pipeline | One failing stage blocks everything | Modularize into reusable workflows or templates |
How ARDURA Consulting accelerates CI/CD implementation
Building a production-grade CI/CD pipeline requires experience with infrastructure automation, container orchestration, security tooling, and cloud platforms. ARDURA Consulting provides:
- Experienced DevOps engineers — from our pool of 500+ senior specialists, we match engineers with hands-on CI/CD experience within 2 weeks
- Platform engineers who have built pipelines for teams of 10 to 500 developers across GitHub Actions, GitLab CI, and Jenkins
- Infrastructure as Code expertise — Terraform, Pulumi, and CloudFormation for pipeline infrastructure
- 40% cost savings compared to hiring equivalent DevOps talent directly in Western Europe
- 99% retention rate — our engineers stay with your project, providing continuity and knowledge retention
- 211+ completed projects across software development, infrastructure, and DevOps
Ready to set up your CI/CD pipeline? Contact ARDURA Consulting for experienced DevOps engineers who can deliver a production-grade pipeline in weeks, not months.
Key takeaways
- Choose your CI/CD tool based on where your code lives and how much infrastructure you want to manage — GitHub Actions for GitHub repos, GitLab CI for all-in-one, Jenkins only for complex on-prem requirements
- Design the pipeline before writing configuration — define stages, speed targets, quality gates, and deployment strategy upfront
- Speed matters — a pipeline over 30 minutes will be bypassed by developers, invest in caching and parallel execution from the start
- Automate rollbacks with clear triggers (error rate, latency, health checks) — manual rollback at 3 AM is not a strategy
- Monitor the pipeline itself — track build duration, success rate, and deployment frequency as first-class metrics