In modern software development, deploying applications efficiently and reliably is crucial. For NestJS applications, implementing a robust CI/CD pipeline ensures seamless integration and deployment. Combining GitHub Actions and Docker provides a powerful workflow that automates testing, building, and deploying your NestJS project.

Understanding CI/CD for NestJS

Continuous Integration (CI) involves automatically testing and integrating code changes, while Continuous Deployment (CD) ensures that these changes are automatically deployed to production or staging environments. Automating these processes reduces manual errors and accelerates release cycles.

Prerequisites

  • GitHub repository with your NestJS project
  • Docker installed locally for testing
  • Access to Docker Hub or a private container registry
  • Basic understanding of GitHub Actions workflows

Setting Up Docker for NestJS

Create a Dockerfile in your project root:

FROM node:14-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

RUN npm run build

EXPOSE 3000

CMD ["node", "dist/main.js"]

Configuring GitHub Actions Workflow

In your repository, create a workflow file at .github/workflows/deploy.yml. This file will define the steps for testing, building, and deploying your NestJS app.

name: CI/CD Pipeline for NestJS

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    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: '14'

      - name: Install dependencies
        run: npm install

      - name: Run tests
        run: npm test

      - name: Build project
        run: npm run build

      - name: Log in to Docker Hub
        uses: docker/login-action@v2
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}

      - name: Build Docker image
        run: docker build -t yourdockerhubusername/nestjs-app:${{ github.sha }} .

      - name: Push Docker image
        run: docker push yourdockerhubusername/nestjs-app:${{ github.sha }}

      - name: Deploy to server
        run: |
          ssh user@yourserver 'docker pull yourdockerhubusername/nestjs-app:${{ github.sha }} && docker stop nestjs-container || true && docker rm nestjs-container || true && docker run -d --name nestjs-container -p 80:3000 yourdockerhubusername/nestjs-app:${{ github.sha }}'
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}

Best Practices

  • Secure your secrets using GitHub Secrets
  • Use tags or commit hashes for image versions
  • Implement health checks and rollback strategies
  • Automate testing and linting before deployment

By following this workflow, you can ensure that your NestJS applications are consistently tested, built, and deployed with minimal manual intervention, leading to faster development cycles and more reliable releases.