Table of Contents
- Introduction
- The Steps
- Step 1: Create a Dockerfile
- Step 2: Optimize Your Dockerfile for Production
- Step 3: Manage Environment Configuration
- Step 4: Building and Running the Docker Image
- Step 5: Implement Health Checks
- Step 6: Integrate with Docker Compose
- Step 7: Use Volumes for Persistent Data
- Step 8: Setting Up Continuous Integration/Continuous Deployment (CI/CD)
- Conclusion
Introduction
Deploying NestJS applications in a containerized environment ensures consistency across various development and production stages. This guide offers step-by-step instructions to dockerize your NestJS application for production using the latest syntax and best practices.
Prerequisites:
- Basic understanding of Docker and its concepts.
- Node.js and NestJS installed on your local machine.
- A NestJS application ready for production.
- Docker installed on your machine.
The Steps
Step 1: Create a Dockerfile
Creating a Dockerfile is the first step in dockerizing your NestJS application. It defines the environment and commands to build your Docker image.
# Start by specifying the base image
FROM node:latest
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json and package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
# Install all node modules
RUN npm install
# Bundle app source
COPY . .
# Build the project
RUN npm run build
# Your app binds to port 3000 so use the EXPOSE instruction
EXPOSE 3000
CMD [ "npm", "run", "start:prod" ]
Step 2: Optimize Your Dockerfile for Production
Optimize your Dockerfile to reduce the image size and improve the build time which is critical for production.
# Use a multi-stage build to reduce the image size
# Stage 1: Build the application
FROM node:latest as builder
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# Stage 2: Setup the production environment
FROM node:alpine
WORKDIR /usr/src/app
COPY --from=builder /usr/src/app/dist ./dist
COPY --from=builder /usr/src/app/node_modules ./node_modules
EXPOSE 3000
CMD [ "node", "dist/main"]
Step 3: Manage Environment Configuration
It’s crucial to separate production-specific environment configurations which can be handled using environment variables with a .env file or directly in the Dockerfile.
# Add a .env file to your Dockerfile during the build process
COPY .env /usr/src/app/.env
# Or you can define environment variables in the Dockerfile directly
ENV PORT=3000
Step 4: Building and Running the Docker Image
With your Dockerfile in place, you can now build the Docker image and run it as a container.
# To build the image:
docker build -t nestjs-app .
# To run the container:
docker run -p 3000:3000 nestjs-app
Step 5: Implement Health Checks
Incorporate health checks to ensure automated systems can monitor the status of services in a container.
# Adding a health check to your Dockerfile
HEALTHCHECK --interval=30s \
--timeout=30s \
CMD node healthcheck.js
Step 6: Integrate with Docker Compose
Use Docker Compose to define and run multi-container Docker applications. Create a docker-compose.yml
file to configure your service.
version: '3'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
Step 7: Use Volumes for Persistent Data
When dealing with databases or files that should persist, volumes are used.
services:
app:
...
database:
image: postgres
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Step 8: Setting Up Continuous Integration/Continuous Deployment (CI/CD)
Integrate your Docker workflow into a CI/CD pipeline to automate testing and deployment.
# Sample GitHub Actions configuration for building and pushing a NestJS Docker image
name: Deploy NestJS App
on:
push:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Docker image
run: docker build . --file Dockerfile --tag mynestjsapp
- name: Push to Registry
run: docker push mynestjsapp
Conclusion
By following this guide, you have dockerized your NestJS application, making it ready for deployment to a production environment. Embrace containerization for its scalability, portability, and consistency across deployment systems.