Deploying NestJS Apps with Docker and Kubernetes: A Complete CI/CD Pipeline

NestJS apps containerized with Docker, deployed on Kubernetes. CI/CD automates builds and deployments. Best practices: use environment variables, health checks, rolling updates, monitoring, and rollback plans. Simplifies scalable, efficient app deployment.

Deploying NestJS Apps with Docker and Kubernetes: A Complete CI/CD Pipeline

Alright, let’s dive into the world of NestJS, Docker, and Kubernetes! If you’re like me, you’ve probably spent countless hours trying to figure out the best way to deploy your apps. Well, buckle up because we’re about to embark on a journey through the land of containers and orchestration.

First things first, let’s talk about NestJS. It’s this awesome TypeScript-based framework that’s been gaining traction lately. I remember when I first stumbled upon it – it was love at first sight. The way it combines elements of OOP, FP, and FRP is just chef’s kiss. But enough gushing, let’s get down to business.

When it comes to deploying NestJS apps, Docker is your best friend. Trust me, I learned this the hard way after countless deployment headaches. Docker lets you package your app and all its dependencies into a neat little container. It’s like wrapping your app in a protective bubble – no matter where it goes, it’ll always have everything it needs.

Here’s a basic Dockerfile for a NestJS app:

FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

EXPOSE 3000

CMD ["npm", "run", "start:prod"]

Pretty straightforward, right? We’re using Node 14, copying our package.json, installing dependencies, building the app, and then running it. Easy peasy.

But here’s where things get interesting. Deploying a single container is cool and all, but what if you want to scale? What if you want zero-downtime deployments? What if you want to easily manage multiple services? Enter Kubernetes.

Kubernetes is like the conductor of an orchestra, making sure all your containers (the musicians) play nicely together. It handles scaling, load balancing, and a whole bunch of other stuff that would otherwise keep you up at night.

To deploy your NestJS app on Kubernetes, you’ll need a few YAML files. Here’s a basic deployment file:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nestjs-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nestjs-app
  template:
    metadata:
      labels:
        app: nestjs-app
    spec:
      containers:
      - name: nestjs-app
        image: your-docker-image:tag
        ports:
        - containerPort: 3000

This tells Kubernetes to create three replicas of your app, making sure there are always three instances running. Pretty cool, huh?

But deploying manually is so last year. What we really want is a CI/CD pipeline. This is where the magic happens. Imagine pushing your code to GitHub and having it automatically tested, built, and deployed. It’s like having your own personal DevOps team.

There are tons of tools out there for setting up CI/CD pipelines. Personally, I’m a fan of GitHub Actions. It’s easy to set up and integrates seamlessly with GitHub. Here’s a basic workflow file:

name: CI/CD

on:
  push:
    branches: [ main ]

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v2
    - name: Build Docker image
      run: docker build -t your-docker-image:${{ github.sha }} .
    - name: Push to Docker Hub
      run: |
        echo ${{ secrets.DOCKER_PASSWORD }} | docker login -u ${{ secrets.DOCKER_USERNAME }} --password-stdin
        docker push your-docker-image:${{ github.sha }}
    - name: Deploy to Kubernetes
      run: |
        kubectl set image deployment/nestjs-app nestjs-app=your-docker-image:${{ github.sha }}

This workflow builds your Docker image, pushes it to Docker Hub, and updates your Kubernetes deployment. It’s like magic, but better because it’s actually real.

Now, let’s talk about some best practices. First, always use environment variables for sensitive information. Never, ever hardcode your database password. Trust me, I learned this the hard way.

Second, use health checks. Kubernetes can use these to know when your app is ready to receive traffic. Here’s a simple health check endpoint in NestJS:

@Get('/health')
healthCheck() {
  return { status: 'ok' };
}

Third, use rolling updates. This allows you to update your app without any downtime. Your users will thank you.

Fourth, monitor everything. Logs, metrics, traces – the works. You can’t fix what you can’t see.

Lastly, always have a rollback plan. Sometimes things go wrong, and you need to be able to quickly revert to a known good state.

Now, you might be thinking, “This all sounds great, but it seems like a lot of work.” And you’re right, it is. But trust me, it’s worth it. The first time you push a change and watch it automatically deploy to production, you’ll feel like a DevOps wizard.

Remember, this is just the tip of the iceberg. There’s so much more to learn about NestJS, Docker, and Kubernetes. But don’t let that intimidate you. Take it one step at a time, and before you know it, you’ll be deploying like a pro.

So go forth and containerize! Deploy with confidence! And most importantly, have fun. Because at the end of the day, we’re all just big kids playing with very expensive toys. Happy coding!