Back to articles
DevOps

How to Deploy a Next.js App on Ubuntu VPS with PM2 and Nginx Reverse Proxy (2026 Guide)

A complete, step-by-step guide to deploying production-ready Next.js apps on an Ubuntu VPS using Node.js, PM2 process manager, Nginx reverse proxy, and free SSL via Certbot.

8 min read

Deploying a Next.js application to your own Virtual Private Server (VPS) offers complete control over resources, predictable hosting costs, and zero platform lock-in. While serverless platforms like Vercel are great for quick prototypes, running Next.js on an Ubuntu VPS backed by PM2 and Nginx Reverse Proxy is the standard architecture for high-performance, cost-effective production deployments.

In this tutorial, you will learn step-by-step how to set up an Ubuntu server from scratch, build your Next.js application, daemonize it with PM2, route web traffic securely using Nginx, and install a free Let's Encrypt SSL certificate.

---

Prerequisites

Before starting, make sure you have:

* An Ubuntu 22.04 or 24.04 LTS VPS (from providers like UltaHost, DigitalOcean, or Linode) with root or sudo access.

* A registered domain name pointed to your VPS IP address (create an `A` record pointing `@` and `www` to your server's Public IP).

* A Next.js codebase hosted on GitHub or GitLab.

---

Step 1: Update Server and Install System Dependencies

SSH into your server:

ssh root@your_server_ip

Update package repositories and install essential build tools:

sudo apt update && sudo apt upgrade -y
sudo apt install -y curl git ufw build-essential

---

Step 2: Install Node.js via NodeSource

Next.js requires modern LTS Node.js. Install Node.js 20 or 22 via NodeSource:

curl -fsSL [https://deb.nodesource.com/setup_20.x](https://deb.nodesource.com/setup_20.x) | sudo -E bash -
sudo apt install -y nodejs

Verify that Node and npm are installed successfully:

node -v
npm -v

---

Step 3: Clone and Build the Next.js Project

A good practice is to host your web apps under `/var/www/`:

sudo mkdir -p /var/www
cd /var/www
sudo git clone [https://github.com/your-username/your-nextjs-repo.git](https://github.com/your-username/your-nextjs-repo.git) my-app
cd my-app

Create your production environment file:

nano .env.production

*(Add your production secrets and API keys, then press `CTRL + O`, `Enter`, and `CTRL + X` to save).*

Install dependencies and generate the production build:

npm install
npm run build

---

Step 4: Manage the Next.js App with PM2

Running `npm start` directly in the terminal will stop the app as soon as your SSH session closes. PM2 is an enterprise process manager that keeps your app running 24/7 and restarts it automatically after server reboots or fatal crashes.

Install PM2 globally:

sudo npm install -g pm2

Start your Next.js application with PM2:

pm2 start npm --name "my-app" -- start

*(Optional)* If you want to use a custom port (e.g., port 3000 or 8080), create an `ecosystem.config.js` in your root directory:

module.exports = {
  apps: [
    {
      name: 'my-app',
      script: 'node_modules/next/dist/bin/next',
      args: 'start -p 3000',
      instances: 'max',
      exec_mode: 'cluster',
      env: {
        NODE_ENV: 'production',
      },
    },
  ],
};

Then start with:

pm2 start ecosystem.config.js

Configure PM2 to persist across system reboots:

pm2 save
pm2 startup

*(Copy and run the `sudo env PATH=...` command generated in your terminal output).*

---

Step 5: Install and Configure Nginx as Reverse Proxy

Nginx receives external HTTPS traffic on port 80/443 and securely forwards requests to your internal Next.js application listening on port 3000.

Install Nginx:

sudo apt install -y nginx

Create a dedicated Nginx server block configuration for your domain:

sudo nano /etc/nginx/sites-available/yourdomain.com

Paste the following optimized configuration (replace `yourdomain.com` with your actual domain):

server {
    listen 80;
    server_name yourdomain.com [www.yourdomain.com](https://www.yourdomain.com);

    # Gzip Compression for fast delivery
    gzip on;
    gzip_proxied any;
    gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    location / {
        proxy_pass [http://127.0.0.1:3000](http://127.0.0.1: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;
        proxy_set_header X-Real-IP$remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto$scheme;
    }
}

Enable the configuration by creating a symlink:

sudo ln -s /etc/nginx/sites-available/yourdomain.com /etc/nginx/sites-enabled/

Test Nginx configuration syntax:

sudo nginx -t

If the test is successful, reload Nginx:

sudo systemctl reload nginx

---

Step 6: Secure Your Server with UFW Firewall & Free SSL

Configure Ubuntu's uncomplicated firewall (UFW) to allow SSH and web traffic:

sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable

Next, install Certbot to generate a free Let's Encrypt SSL certificate:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d [www.yourdomain.com](https://www.yourdomain.com)

Follow the interactive prompts. Certbot will automatically issue the certificate, configure HTTPS redirect rules inside your Nginx configuration, and set up an automatic renewal cron job.

---

Step 7: Zero-Downtime Deployment Workflow

Whenever you push updates to GitHub, update your live app with this simple deployment sequence:

cd /var/www/my-app
git pull origin main
npm install
npm run build
pm2 reload my-app

Using `pm2 reload` instead of `pm2 restart` performs a graceful reload with zero downtime for incoming visitors.

---

Conclusion

Your Next.js application is now fully deployed on your Ubuntu VPS with production-grade stability, automated process monitoring via PM2, high-throughput caching via Nginx, and complete HTTPS encryption.

Looking for an affordable, high-performance NVMe VPS to deploy your Next.js projects? Check out UltaHost VPS Plans starting at just $4.50/month with zero renewal price shocks.

Found this helpful?Share this article with your network to help others discover useful AI insights.

Share your thoughts on X or Facebook