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

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:

```plaintext
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**

```plaintext
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.

```javascript
// 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.

```json
{
  "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.

```dockerfile
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.

```yaml
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:

```plaintext
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**

```yaml
- name: Run Linter
  run: npm run lint
```

### **B. Add Unit Tests (Jest)**

```plaintext
npm install jest --save-dev
```

```json
"scripts": {
  "test": "jest"
}
```

### **C. Multi-Environment Deployment**

```yaml
if: github.ref == 'refs/heads/staging'
```

*   staging branch → staging server
    
*   main branch → production
    

### **D. Zero-Downtime Deployment (Blue-Green)**

Instead of stopping container:

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

### **E. Kubernetes Deployment (Optional Upgrade)**

Replace Docker run with:

```plaintext
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
