Deploy Next.js App on Ubuntu with Nginx and PM2

· #linux#nginx#pm2#nextjs

PM2 is a production process manager for Node.js applications with a built-in load balancer. It allows you to keep applications alive forever, to reload them without downtime and to facilitate common system admin tasks.


Setup

1. Install Node.js

We’ll use nvm to install Node.js.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
\. "$HOME/.nvm/nvm.sh"
nvm install 24

Install bun.

sudo npm install -g bun

2. Setup Next.js App

Install PM2.

sudo npm install -g pm2

Create a new ecosystem.config.js file in your project root directory. You should commit this file.

module.exports = {
  apps: [
    {
      name: 'next-app',
      port: '3000',
      script: 'npm',
      args: 'start',
      env: {
        NODE_ENV: 'development',
        AWS_REGION: process.env.AWS_REGION,
        AWS_ACCESS_KEY_ID: process.env.AWS_ACCESS_KEY_ID,
        AWS_SECRET_ACCESS_KEY: process.env.AWS_SECRET_ACCESS_KEY,
        // Add your env variables here
      },
    },
  ],
}

Clone and build the app.

cd
git clone git@github.com:user/next-app.git next-app
mv next-app /var/www/next-app/
cd /var/www/next-app
bun install --frozen-lockfile
bun run build

Start the app in background via PM2.

pm2 start ecosystem.config.js
pm2 save  # Save the process lists
pm2 startup
pm2 startup systemd -u ubuntu --hp /home/ubuntu  # Ensure to start the daemon on reboot
pm2 list  # See all processes

If you update your app, you can reload PM2 with:

pm2 reload ecosystem.config.js

3. Configure NGINX

Install NGINX

sudo apt install nginx

Create a new file /etc/nginx/sites-available/next-app, and add:

server {
  listen 80;
  server_name _;

  location / {
    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade \$http_upgrade;
    proxy_set_header Connection 'upgrade';
    proxy_set_header Host \$host;
    proxy_cache_bypass \$http_upgrade;
  }
}

Enable the site

sudo rm /etc/nginx/sites-enabled/default
sudo ln -s /etc/nginx/sites-available/next-app /etc/nginx/sites-enabled/

Reload NGINX and PM2

pm2 reload 'next-app'
sudo systemctl enable nginx
sudo systemctl restart nginx

4. Setup Firewall

sudo ufw allow 80,443/tcp

5. Set Up SSL (Optional)

To secure your site with HTTPS, you can use Let’s Encrypt to obtain an SSL certificate:

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com

References

  1. https://nodejs.org/en/download/package-manager
  2. https://pm2.keymetrics.io/