Seamless Next.js Deployment on EC2 with PM2 & Nginx
Note: We've mirrored this post from Substack to provide easy access alongside other content. While we strive for accuracy, the original Substack post may offer richer formatting or embedded media. For the definitive reading experience, please visit the original article.
Read on Substack →Deploying a NextJS App on EC2 Using PM2 and Nginx Without Downtime
In this guide, we'll explore how to deploy a NextJS application on Amazon EC2 (or any server) using PM2 and Nginx, ensuring zero downtime during updates.
Required Tools
Nginx: A powerful web server and reverse proxy.
PM2: A process manager for Node.js applications that helps with deployment and runtime management.
Understanding PM2
PM2 is a crucial tool for managing Node.js apps. It simplifies starting, stopping, and monitoring applications. You can learn more about it in the PM2 Documentation. Here’s a basic example of deploying a Node.js application with PM2:
pm2 start api.js
PM2 also supports configuration files to manage multiple applications:
module.exports = {
apps: [
{
name: "limit worker",
script: "./worker.js",
args: "limit",
},
{
name: "rotate worker",
script: "./worker.js",
args: "rotate",
},
],
};
Deploying NextJS with PM2
To deploy a NextJS application, follow these steps:
Build Your Application: Run the build command to compile your NextJS app into production-ready files.
npm run build
Start Your Server: Use PM2 to start your NextJS app.
pm2 start npm -- start
This command initiates your app on the default port 3000 using PM2, handling application starts and restarts automatically.
NextJS Zero Downtime deployment with PM2 Cluster Mode
Deploying updates might cause temporary downtime due to changes in the build directory. To avoid this, use PM2's cluster mode, which optimizes CPU usage and maintains service availability:
Configure PM2 for Cluster Mode: Modify your package.json scripts and create a PM2 ecosystem configuration file (
ecosystem.config.js
) to specify cluster mode settings:
package.json
"scripts": {
"lint": "next lint",
"dev": "next dev",
"build": "next build",
"start": "node server.js",
"preprods": "NODE_ENV=production next start",
"prettier": "prettier --write \"*.{json,js,md,yaml,yml}\"",
"lint:js": "npm run prettier && eslint --fix .",
"analyze": "ANALYZE=true npm run build",
"prepare": "husky install"
}
ecosystem.config.js
module.exports = {
apps: [
{
name: "name of your app",
script: "npm", // npm start
args: "run preprods", // Check package json above
listen_timeout: 12000, // Hack Without timeout we will get downtime in deployment
cwd: "/home/ubuntu/rajat", // Command execution path
instances: "max", // Max Use all the CPU
exec_mode: "cluster", // Clustor Mode
increment_var: "PORT", // It will auto increment port your app will run on 3001, 3002 and so on
env_production: {
PORT: 3000, // Default Port
NODE_ENV: "production", // Production Env
},
// You can configure for multiple environments
},
],
};
Start the PM2 Process: Begin the deployment with your new configuration to enable zero downtime:
pm2 start ecosystem.config.js --env production
Update and Restart: Whenever you need to update your application:
npm run build && pm2 restart all
This streamlined process ensures your NextJS application runs smoothly on EC2 or any other server, utilizing PM2 for efficient management and Nginx for secure and fast content delivery.