Skip to main content

Command Palette

Search for a command to run...

End-to-End CI/CD Pipeline Tutorial (Beginner → Advanced)

Updated
•5 min read•View as Markdown
N
Global tech creator.

This tutorial provides a complete, production-grade walkthrough of building a CI/CD (Continuous Integration / Continuous Deployment) pipeline. It covers architecture, tooling, pipeline design, automation workflows, and full working code examples using GitHub Actions, Docker, and deployment strategies.

1. What is CI/CD (Conceptual Foundation)

Continuous Integration (CI)

  • Developers push code frequently to a shared repository.

  • Automated processes:

    • Build

    • Test

    • Lint

  • Objective: detect issues early.

Continuous Deployment (CD)

  • Automatically deploy validated code to:

    • staging

    • production

  • Eliminates manual release bottlenecks.

2. CI/CD Architecture Overview

A typical pipeline:

Developer → Git Push → CI Pipeline → Build → Test → Artifact → CD Pipeline → Deploy → Monitor

Components:

  • Version Control: GitHub / GitLab

  • CI Tool: GitHub Actions

  • Build Tool: Docker

  • Artifact Storage: Docker Registry

  • Deployment Target: VPS / Cloud / Kubernetes

3. Project Setup (Example App)

We’ll use a simple Node.js app.

Project Structure

project/
├── app.js
├── package.json
├── Dockerfile
└── .github/
    └── workflows/
        └── ci-cd.yml

Code: Node.js App

Title: Basic Node.js Web Server

Description: A minimal HTTP server used to demonstrate CI/CD workflow.

// app.js
const http = require('http');

const PORT = process.env.PORT || 3000;

const server = http.createServer((req, res) => {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.end('CI/CD Pipeline Working!');
});

server.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

package.json

Title: Node Project Configuration

Description: Defines dependencies and scripts for build/test stages.

{
  "name": "ci-cd-demo",
  "version": "1.0.0",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "echo \"No tests yet\" && exit 0"
  }
}

4. Dockerization

Dockerfile

Title: Docker Image Definition

Description: Builds a container image for consistent deployment across environments.

FROM node:18

WORKDIR /app

COPY package.json .
RUN npm install

COPY . .

EXPOSE 3000

CMD ["npm", "start"]

5. CI Pipeline (GitHub Actions)

Workflow File

Title: CI/CD Pipeline Workflow

Description: Automates build, test, Docker image creation, and deployment.

name: CI/CD Pipeline

on:
  push:
    branches:
      - main

jobs:
  build-test:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: 1

  - name: Install Dependencies
    run: npm install

  - name: Run Tests
    run: npm test

  docker-build:
    needs: build-test
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v3

 - name: Login to Docker Hub
    run: echo "\({{ secrets.DOCKER_PASSWORD }}" | docker login -u "\){{ secrets.DOCKER_USERNAME }}" --password-stdin

   - name: Build Docker Image
        run: docker build -t ${{ secrets.DOCKER_USERNAME }}/ci-cd-demo:latest .

      - name: Push Docker Image
        run: docker push ${{ secrets.DOCKER_USERNAME }}/ci-cd-demo:latest

  deploy:
    needs: docker-build
    runs-on: ubuntu-latest

    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@v0.1.6
        with:

   host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SERVER_SSH_KEY }}
          script: |

  docker pull ${{ secrets.DOCKER_USERNAME }}/ci-cd-demo:latest
            docker stop app || true
            docker rm app || true
            docker run -d -p 80:3000 --name app ${{ secrets.DOCKER_USERNAME }}/ci-cd-demo:latest

6. Secrets Configuration

In your repository settings:

Required secrets:

DOCKER_USERNAME
DOCKER_PASSWORD
SERVER_HOST
SERVER_USER
SERVER_SSH_KEY

7. Deployment Flow (Step-by-Step)

  1. Developer pushes code to main

  2. GitHub Actions triggers pipeline

  3. CI Stage:

    • install dependencies

    • run tests

  4. Build Stage:

    • create Docker image

    • push to Docker Hub

  5. CD Stage:

    • SSH into server

    • pull latest image

    • restart container

8. Advanced Enhancements

A. Add Linting

- name: Run Linter
  run: npm run lint

B. Add Unit Tests (Jest)

npm install jest --save-dev
"scripts": {
  "test": "jest"
}

C. Multi-Environment Deployment

if: github.ref == 'refs/heads/staging'
  • staging branch → staging server

  • main branch → production

D. Zero-Downtime Deployment (Blue-Green)

Instead of stopping container:

app-v1 → running
app-v2 → start
switch traffic → remove v1

E. Kubernetes Deployment (Optional Upgrade)

Replace Docker run with:

kubectl apply -f deployment.yaml

9. Common Failure Points

Issue Cause Fix
Pipeline fails at install Dependency mismatch Lock versions
Docker push fails Auth issue Check secrets
SSH deploy fails Wrong key Verify permissions
App not accessible Port mismatch Check EXPOSE vs run

10. Best Practices

  • Keep pipelines idempotent

  • Use immutable artifacts

  • Separate build and deploy stages

  • Never hardcode secrets

  • Use branch protection rules

  • Monitor deployments (logs, uptime)

11. CI/CD Maturity Model

Level Description
Basic Manual deploy
Intermediate CI + manual CD
Advanced Fully automated
Elite Auto rollback + monitoring

12. Final Outcome

After implementing this:

  • Every push → automatically tested

  • Every valid build → deployed

  • No manual release needed

4 views