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 GitHubKUBECONFIG
: 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.
Subscribe to my newsletter
Read articles from Saikrishna Yalamati directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
