Complete CI/CD Pipeline for Dockerized Node.js Apps on Kubernetes

In modern software development, continuous integration and continuous deployment (CI/CD) are essential for delivering high-quality applications rapidly and reliably. This article demonstrates a complete CI/CD pipeline using GitHub Actions for a Node.js application, containerized with Docker, and deployed to a Kubernetes (K8s) cluster.

The workflow includes steps to:

  • Build and test the application

  • Build a Docker image and push it to GitHub Container Registry (GHCR)

  • Deploy the application to a Kubernetes cluster using kubectl


πŸš€ GitHub Actions CI/CD Pipeline: ci-cd.yml

# .github/workflows/ci-cd.yml
name: CI/CD Pipeline

on:
  push:
    branches:
      - main
      - develop
  pull_request:

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build-test:
    name: Build & Test
    runs-on: ubuntu-latest

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

      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm install

      - name: Run Linter
        run: npm run lint

      - name: Run Tests
        run: npm test

  dockerize:
    name: Build & Push Docker Image
    runs-on: ubuntu-latest
    needs: build-test
    permissions:
      contents: read
      packages: write

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

      - name: Log in to GitHub Container Registry
        uses: docker/login-action@v2
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build Docker image
        run: |
          docker build -t $REGISTRY/${{ env.IMAGE_NAME }}:latest .

      - name: Push Docker image
        run: |
          docker push $REGISTRY/${{ env.IMAGE_NAME }}:latest

  deploy:
    name: Deploy to Kubernetes
    runs-on: ubuntu-latest
    needs: dockerize

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

      - name: Set up Kubeconfig
        run: |
          mkdir -p ~/.kube
          echo "${{ secrets.KUBECONFIG }}" > ~/.kube/config

      - name: Set Image in Deployment YAML
        run: |
          sed -i "s|image: .*|image: $REGISTRY/${{ env.IMAGE_NAME }}:latest|" k8s/deployment.yaml

      - name: Deploy to Cluster
        run: |
          kubectl apply -f k8s/

πŸ“ Folder Structure

.
β”œβ”€β”€ .github/workflows/ci-cd.yml
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ k8s/
β”‚   └── deployment.yaml
β”œβ”€β”€ package.json
└── src/

🐳 Sample Dockerfile

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install --production
COPY . .
CMD ["npm", "start"]

☸️ Sample deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: my-app
          image: ghcr.io/your-org/your-repo:latest
          ports:
            - containerPort: 3000

βœ… Secrets You’ll Need

  • GITHUB_TOKEN: auto-injected by GitHub

  • KUBECONFIG: base64 or raw kubeconfig for your cluster (stored in GitHub secrets)


βœ… Conclusion

With this CI/CD pipeline in place, every push to the main or develop branch triggers an automated process that ensures code quality, builds your application, packages it in a Docker container, and deploys it to your Kubernetes clusterβ€”saving time and reducing errors.

Whether you're running a personal project or managing enterprise-grade infrastructure, this GitHub Actions workflow provides a robust starting point for automated, repeatable, and scalable deployments.

By automating the entire delivery lifecycle, your team can focus more on building features and less on managing deployments.

1
Subscribe to my newsletter

Read articles from Saikrishna Yalamati directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Saikrishna Yalamati
Saikrishna Yalamati