This episode covers DevOps for NestJS: CI/CD pipelines with GitHub Actions and GitLab CI, automated testing and linting, automated deployment, canary release and blue-green deployment strategies with rollback, plus Infrastructure as Code.

Manual deployment is a source of errors and delays. CI/CD automates the entire code journey — from commit to production — with tests and checks at every step. Episode 21 covers DevOps practices for NestJS applications.
You'll build a pipeline that tests, builds, and deploys the application automatically.
GitHub Actions runs on events like pushes and pull requests:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm run lint
- run: npm run test -- --coverage
- run: npm run buildEvery push to main triggers: install dependencies, lint, test, and build. If any step fails, the pipeline stops.
GitLab CI uses the .gitlab-ci.yml file with the concept of stages:
stages:
- test
- build
- deploy
test:
stage: test
image: node:22
script:
- npm ci
- npm run lint
- npm run test
- npm run build
build:
stage: build
image: docker:latest
script:
- docker build -t $CI_REGISTRY_IMAGE .
- docker push $CI_REGISTRY_IMAGEThe conceptual approach is the same: sequential stages, each with its own image and script.
A CI pipeline must run quality checks before deploying: lint, unit tests, integration tests, and build. Never deploy code that fails tests. Coverage can be given a minimum threshold so a drop in quality automatically blocks the pipeline.
Caching node_modules speeds up the pipeline:
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ciWith cache: npm, dependencies are cached between runs — making the pipeline much faster.
After tests pass, the pipeline builds the image and deploys:
build:
runs-on: ubuntu-latest
needs: test
steps:
- uses: actions/checkout@v4
- run: docker build -t registry.example.com/nestjs-api:${{ github.sha }} .
- run: docker push registry.example.com/nestjs-api:${{ github.sha }}Images are tagged with the commit SHA — every deployment can be traced to a specific commit.
Blue-green keeps two environments: the old version (blue) and the new version (green). Traffic is switched from blue to green once green is healthy. If a problem is found, traffic can be switched straight back to blue — instant rollback without downtime.
A canary release sends the new version to a small fraction of users first, then gradually to everyone if metrics look healthy:
spec:
strategy:
canary:
steps:
- setWeight: 10
- pause: { duration: 10m }
- setWeight: 50
- pause: { duration: 10m }Argo Rollouts and Flagger enable this strategy on Kubernetes. Automatic rollback happens if error metrics rise while the canary is running.
Every deployment must be rollback-able quickly. Best practices: keep the old image, version the deployment in Git, and use health checks as a health marker. With blue-green, rollback only moves traffic — no rebuild needed.
Infrastructure as Code (IaC) defines infrastructure as code that can be reviewed and versioned:
resource "aws_ecs_service" "api" {
name = "nestjs-api"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.api.arn
desired_count = 3
load_balancer {
target_group_arn = aws_lb_target_group.api.arn
container_name = "api"
container_port = 3000
}
}With Terraform, the entire infrastructure — cluster, load balancer, database — is defined in code and applied reproducibly.
Episode 21 automates the NestJS code journey: CI/CD with GitHub Actions and GitLab CI, automated testing, automated deployment, blue-green and canary strategies, and Infrastructure as Code.
Key takeaways:
In the next episode 22 we'll discuss observability and production support — distributed tracing and OpenTelemetry integration, centralized logging and correlation IDs, monitoring metrics and alerts, plus incident response and troubleshooting in production.