Scaling your Nestjs application with Zero Downtime deployment
Scaling your Nestjs application with Zero Downtime deployment
To avoid interrupting service when building a project in NestJS and running the service with PM2, you can use several strategies. The most effective method is to use zero-downtime deployment practices.
Because rimraf dist
is used before building the project, you can adopt a strategy that involves building the new version of your project in a separate directory and then performing a smooth switch.
Here’s a detailed step-by-step approach:
- Build in a Temporary Directory: Instead of directly building into the
dist
directory, build your project into a temporary directory. - Use PM2 to Reload the Application: After the build is complete, use PM2 to reload the application from the new build directory.
- Swap Directories: Once the reload is successful, swap the
dist
directory with the new build directory.
Detailed Implementation
Modify Your Build Script: Adjust your build script to output to a temporary directory (e.g., dist-new
). Update your package.json
scripts:
{
"scripts": {
"prebuild": "rimraf dist-new",
"build": "nest build"
}
}
Modify your tsconfig.build.json
to specify a different output directory.
{
"compilerOptions": {
"outDir": "./dist-new", // Change to dist-new
"rootDir": "./src",
"module": "commonjs",
"target": "es2017",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"skipLibCheck": true,
"strict": true
},
"include": ["src/**/*.ts"],
"exclude": ["node_modules", "test", "dist", "**/*spec.ts"]
}
Deploy Script: Create a deployment script to handle the build process, directory swap, and PM2 reload. Create a deploy.sh
script:
#!/bin/bash
# Step 1: Build the new version into a temporary directory
echo "Building the project..."
npm run build
# Step 2: Check if build was successful
if [ $? -ne 0 ]; then
echo "Build failed. Exiting."
exit 1
fi
# Step 3: Copy current dist to a backup directory
echo "Backing up current dist directory..."
mv dist dist-backup
# Step 4: Move new build to dist directory
echo "Swapping dist directories..."
mv dist-new dist
# Step 5: Reload PM2 with zero downtime
echo "Reloading PM2..."
pm2 reload all
# Step 6: Cleanup backup
echo "Cleaning up backup..."
rm -rf dist-backup
echo "Deployment completed successfully."
Make Script Executable: Ensure the deployment script is executable then run
chmod +x deploy.sh
./deploy.sh
Explanation:
- TypeScript Configuration (
tsconfig.build.json
): Specifies that the output should go to a new directory (dist-new
). - Build Script (
package.json
): Defines the build steps to first remove the olddist-new
directory and then build the project using the specifiedtsconfig
. - Deployment Script (
deploy.sh
): Manages the build process, directory swaps, and PM2 reloading to ensure zero downtime.
This approach ensures that the service is not interrupted during the build and deployment process. The application continues to run from the current dist
directory until the new build is ready and swapped in.