← Back to Blog

Seamless Next.js Deployment on EC2 with PM2 & Nginx

By Rajat DhootMay 1, 2025

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:

Thanks for reading Rajat’s Substack! Subscribe for free to receive new posts and support my work.

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:

  1. Build Your Application: Run the build command to compile your NextJS app into production-ready files.

npm run build
  1. 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:

  1. 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
    },
  ],
};
  1. Start the PM2 Process: Begin the deployment with your new configuration to enable zero downtime:

pm2 start ecosystem.config.js --env production

Start writing today. Use the button below to create a Substack of your own

Start a Substack

  1. 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.

Thanks for reading Rajat’s Substack! Subscribe for free to receive new posts and support my work.