Deploying Next.js with PM2: Multiple Instances on Custom Ports

Jan 7, 2025

Learn how to deploy Next.js applications with PM2, configure multiple instances on custom ports, and implement load balancing for improved performance and availability.

Deploying Next.js with PM2: Multiple Instances on Custom Ports

Deploying Next.js applications with PM2, especially when aiming for pm2 nextjs multiple instances custom ports, requires a solid understanding of both tools. PM2 is a powerful process manager for Node.js that allows you to keep your applications running reliably, and Next.js is a popular React framework for building full-stack applications. This article will explore how to configure PM2 to launch multiple instances of a Next.js application, each on a custom port, enhancing performance and availability.

Understanding the Challenge of Multiple Instances on the Same Port

Running multiple instances of a server application on the same port is not possible, as each instance would compete for the same network address. Attempting to do so results in an "EADDRINUSE" error, indicating that the address is already in use. Therefore, when configuring pm2 nextjs multiple instances custom ports, each instance must have its own unique port assignment. This can be accomplished through various methods, such as defining environment variables or using command-line arguments.

Setting Custom Ports for Next.js with PM2

There are several approaches to setting custom ports when using pm2 nextjs multiple instances custom ports, depending on your needs and preferences. The most common involve modifying the package.json file or utilizing a PM2 configuration file (ecosystem.config.js). Let's explore these options:

Modifying the package.json scripts

One straightforward method is to define the port within your package.json file in the scripts section. For example, you can modify the start script to include the -p flag followed by your desired port number. This approach is suitable when you need a specific port for all instances, but it is not ideal for managing multiple instances with different ports.

 "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p 3002"
  },

Credit: stackoverflow.com

Utilizing ecosystem.config.js for Flexible Configurations

For more advanced control, especially when dealing with pm2 nextjs multiple instances custom ports, creating an ecosystem.config.js file is highly recommended. This file allows you to define multiple applications with custom settings, including different ports.

Setting Environment Variables in ecosystem.config.js

One approach within ecosystem.config.js is to use environment variables to specify the port each instance should use. This involves setting a PORT variable within the env object.

module.exports = {
  apps: [
    {
      name: 'nextjs-app',
      script: 'npm',
      args: 'start -- -p 3000',
      instances: 'max',
      exec_mode: 'cluster'
    }
  ]
};

Credit: medium.com

This configuration starts your app using the npm start command, and the -- -p 3000 argument passes the port number to the Next.js server. The instances: 'max' setting allows PM2 to use all available CPU cores, and exec_mode: 'cluster' enables load balancing across those instances.

Incrementing Port Numbers for Multiple Instances

To run multiple instances on different ports, you can use PM2's increment_var feature. This allows you to automatically increment a variable (like PORT) for each instance.

module.exports = {
  apps : [
      {
        name: "myapp",
        script: "./app.js",
        instances: 4,
        exec_mode: "cluster",
        watch: true,
        increment_var : 'PORT',
        env: {
            "PORT": 3000,
            "NODE_ENV": "development"
        }
      }
  ]
}

Credit: github.com

In this setup, the application starts with PORT=3000 and increments to 3001, 3002, and 3003 for each subsequent instance.

Managing Multiple Next.js Instances with PM2

Once you've configured PM2, you can manage your pm2 nextjs multiple instances custom ports with several commands.

  • pm2 start ecosystem.config.js: Starts all applications defined in the configuration file.
  • pm2 reload nextjs-app: Reloads the application without downtime.
  • pm2 monit: Provides a live view of your applications' status and logs.
  • pm2 logs <app_name>: Displays the logs of a specific application.

Considerations for Load Balancing

When running multiple instances of your Next.js application, you'll likely want to implement load balancing to distribute traffic effectively. PM2's cluster mode provides basic load balancing. For more advanced needs, consider using a reverse proxy like Nginx or Open LiteSpeed.

Using Nginx as a Reverse Proxy

Nginx can be configured to distribute incoming requests across multiple backend servers, each running a Next.js instance on a different port.

upstream my_nodejs_upstream {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
    server 127.0.0.1:3003;
    keepalive 64;
}

server {
    listen 443 ssl;
    
    server_name www.my-website.com;
    ssl_certificate_key /etc/ssl/main.key;
    ssl_certificate     /etc/ssl/main.crt;
   
    location / {
    	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Real-IP $remote_addr;
    	proxy_set_header Host $http_host;
        
    	proxy_http_version 1.1;
    	proxy_set_header Upgrade $http_upgrade;
    	proxy_set_header Connection "upgrade";
        
    	proxy_pass http://my_nodejs_upstream/;
    	proxy_redirect off;
    	proxy_read_timeout 240s;
    }
}

Credit: github.com

This configuration routes traffic to your application running on different ports, allowing you to take full advantage of your server's resources.

Using Open Lite Speed as a Reverse Proxy

Open Lite Speed is another option for a reverse proxy. It has a web-based administration panel, which makes configuration easier.

Add virtual host Credit: ryusei.io

You can define virtual hosts and link them to external applications running on different ports. The configuration of a proxy in Open Lite Speed involves setting the destination port, and then linking it to a domain.

Conclusion

Successfully deploying a Next.js application with pm2 nextjs multiple instances custom ports requires careful planning and configuration. You must ensure that each instance runs on a unique port and consider load balancing to distribute traffic evenly. By using the methods outlined in this article, you can effectively manage multiple instances of your application, improving performance and availability. Remember to use configuration files such as ecosystem.config.js for greater flexibility and control. This strategy will enable you to maximize the utilization of your server resources and create a more robust and scalable application.

Recent Posts