How to Deploy Next.js on Ubuntu 26.04 with PM2, Nginx, and PostgreSQL

How to Deploy Next.js on Ubuntu 26.04 with PM2 Nginx and PostgreSQL

In this blog post, we will show you how to deploy a Next.js application with PM2, Nginx, and PostgreSQL on Ubuntu 26.04 OS. A Next.js application can be deployed using PM2, Nginx, and PostgreSQL to create a reliable and efficient web environment. Next.js handles the frontend and backend logic, providing a fast and responsive user experience. PM2 manages the application process, keeps it running in the background, and automatically restarts it if something goes wrong. Nginx acts as a reverse proxy, handling incoming HTTP/HTTPS requests and forwarding them to the Next.js application. PostgreSQL serves as the database, storing application data securely and efficiently. Together, these technologies provide a solid foundation for building, deploying, and maintaining modern web applications.

This setup will take about 20 minutes to make fully functional. Let’s start!

Prerequisites

  • A server running Ubuntu 26.04 OS
  • User privileges: root or a non-root user with sudo privileges
  • A valid domain with an A record to the server

Step 1. Update the System

Before installing anything on the server, make sure your system packages are up to date. Run the following command to upgrade everything to the newest versions:

apt update -y && apt upgrade -y

Step 2. Install PostgreSQL Database Service

PostgreSQL stores, organizes, and manages the application’s data, providing a reliable, secure database for queries, user information, and other application-related records.

To install the PostgreSQL database service, execute the command below:

apt-get install postgresql -y

Next up, enable the PostgreSQL service. You need to do the following:

systemctl start postgresql && systemctl enable postgresql

To check the status of the service:

systemctl status postgresql

You should get output similar to this:

root@host:~# systemctl status postgresql
● postgresql.service - PostgreSQL RDBMS
     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; preset: enabled)
     Active: active (exited) since Wed 2026-10-14 10:49:13 CDT; 31s ago
 Invocation: 87ce4d2327044673a24168800c448723
   Main PID: 3794 (code=exited, status=0/SUCCESS)
   Mem peak: 1.7M
        CPU: 13ms

Oct 14 10:49:13 host.test.vps systemd[1]: Starting postgresql.service - PostgreSQL RDBMS...
Oct 14 10:49:13 host.test.vps systemd[1]: Finished postgresql.service - PostgreSQL RDBMS.

Step 3. Install NodeJS

Node.js provides the runtime environment needed to run the Next.js application, while npm is used to install and manage project dependencies and run application scripts. PM2 manages the application process, keeping it running in the background and automatically restarting it if it crashes.

The fastest way to install NodeJS is using the default system repository. NodeJS is included in the Ubuntu 26.04 repository, so to install it, simply execute the following command:

apt install nodejs npm -y

Once installed, you can verify the installation with the command below:

node -v && npm -v

You should get the following output:

root@host:~# node -v && npm -v
v22.22.1
9.2.0

Step 4. Install PM2 Globally

PM2 is a process management tool designed for production environments. It keeps your application running, supports zero-downtime reloads, and can automatically start your application again after a system reboot. To install PM2 globally using npm, run the following command:

npm install -g pm2

To check the installed PM2 version, execute the following command:

pm2 -v

You should get the following output:

oot@host:~# pm2 -v

                        -------------

__/\\\\\\\\\\\\\____/\\\\____________/\\\\____/\\\\\\\\\_____
 _\/\\\/////////\\\_\/\\\\\\________/\\\\\\__/\\\///////\\\___
  _\/\\\_______\/\\\_\/\\\//\\\____/\\\//\\\_\///______\//\\\__
   _\/\\\\\\\\\\\\\/__\/\\\\///\\\/\\\/_\/\\\___________/\\\/___
    _\/\\\/////////____\/\\\__\///\\\/___\/\\\________/\\\//_____
     _\/\\\_____________\/\\\____\///_____\/\\\_____/\\\//________
      _\/\\\_____________\/\\\_____________\/\\\___/\\\/___________
       _\/\\\_____________\/\\\_____________\/\\\__/\\\\\\\\\\\\\\\_
        _\///______________\///______________\///__\///////////////__


                          Runtime Edition

        PM2 is a Production Process Manager for Node.js applications
                     with a built-in Load Balancer.

                Start and Daemonize any application:
                $ pm2 start app.js

                Load Balance 4 instances of api.js:
                $ pm2 start api.js -i 4

                Monitor in production:
                $ pm2 monitor

                Make pm2 auto-boot at server restart:
                $ pm2 startup

                To go further checkout:
                http://pm2.io/


                        -------------

[PM2] Spawning PM2 daemon with pm2_home=/root/.pm2
[PM2] PM2 Successfully daemonized
7.0.4

Step 5. Create a Node.js database, a database user, and assign permissions

First, log in to the PostgreSQL command-line tool:

sudo -i -u postgres psql

Once logged in, execute the following commands one by one:

CREATE DATABASE nextjs_db;

CREATE USER nextjs_user WITH PASSWORD 'YourStrongPasswordHere';

GRANT ALL PRIVILEGES ON DATABASE nextjs_db TO nextjs_user;

ALTER DATABASE nextjs_db OWNER TO nextjs_user;

\q

Step 6. Create a Next.JS application with NPM

Now that all the required server components are installed, we can create a test Next.js application using npm by running the following command:

cd /opt

npm create next-app@latest my-nextjs-app

After running it, confirm the next app version and the recommended Next.js defaults. After the installation is completed, the output should look like this:

root@test opt]# npm create next-app@latest my-nextjs-app
Need to install the following packages:
create-next-app@16.2.10
Ok to proceed? (y) y


> npx
> create-next-app my-nextjs-app

✔ Would you like to use the recommended Next.js defaults? › Yes, use recommended defaults
Creating a new Next.js app in /opt/my-nextjs-app.

Using npm.

Initializing project with template: app-tw 


Installing dependencies:
- next
- react
- react-dom

Installing devDependencies:
- @tailwindcss/postcss
- @types/node
- @types/react
 .
 .
 .
 .
 .

Run `npm audit` for details.

Generating route types...
✓ Types generated successfully

Initialized a git repository.

Success! Created my-nextjs-app at /opt/my-nextjs-app

Once the NextJS app is created, create a production environment file (.env.production or .env) to feed connection variables to your application, including the local PostgreSQL connection string with the credentials we set in step number five:

/opt/my-nextjs-app && nano .env.production

Paste the following lines of code:

DATABASE_URL="postgresql://nextjs_user:YourStrongPasswordHere@localhost:5432/nextjs_db"
NODE_ENV="production"

Save the file and close it.

Next, fetch packages and build the optimized production code:

npm ci

npm run build

Step 7. Start the NextJS application with PM2

After creating and building the Next.js application, we can launch it using PM2 with the following command:

pm2 start npm --name "my-nextjs-app" -- start -- --hostname 0.0.0.0 --port 3000

To verify that the Next.js application is running correctly, use the following command to check its status:

pm2 status

The output should look similar to the following:

Deploy Next.js on Ubuntu 26.04

As you can see, the ID of the application is 0, so we can manage the NextJS application with the following commands:

pm2 status 0            # Show the current status of the application
pm2 show 0              # Display detailed information about the process
pm2 logs 0              # Stream the application's logs (stdout and stderr)
pm2 logs 0 --lines 100  # Show the last 100 log lines and continue streaming

pm2 restart 0       # Restart the application
pm2 reload 0        # Gracefully reload the application (if supported)
pm2 stop 0          # Stop the application without removing it from PM2
pm2 start 0         # Start the application again after it has been stopped
pm2 delete 0        # Remove the application from PM2

pm2 monit           # Open the real-time PM2 monitoring dashboard
pm2 list            # List all applications managed by PM2
pm2 save            # Save the current PM2 process list for startup restoration
pm2 resurrect       # Restore the previously saved process list

pm2 flush           # Clear all PM2 log files
pm2 reloadLogs      # Reopen log files without restarting applications

pm2 startup         # Generate the command to start PM2 automatically on system boot

Step 8. Install Nginx and Configure a Reverse Proxy

Nginx acts as a reverse proxy, handling incoming HTTP/HTTPS requests, managing SSL certificates, and forwarding traffic to the Next.js application running under PM2. To install Nginx, execute the following command:

apt install nginx -y

Once installed, start and enable the Nginx service:

systemctl start nginx && systemctl enable nginx

To check the status of the service, you can execute the command below:

systemctl status nginx

You should receive the following output:

root@host:/opt/my-nextjs-app# systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; preset: enabled)
     Active: active (running) since Wed 2026-10-14 13:21:17 CDT; 35s ago
 Invocation: ce8ac6a0fd0445d4877677297e253980
       Docs: man:nginx(8)
   Main PID: 12777 (nginx)
      Tasks: 4 (limit: 3767)
     Memory: 3.9M (peak: 9M)
        CPU: 103ms
     CGroup: /system.slice/nginx.service
             ├─12777 "nginx: master process /usr/sbin/nginx -g daemon on; master_process on;"
             ├─12780 "nginx: worker process"
             ├─12781 "nginx: worker process"
             └─12782 "nginx: worker process"

Create a custom Nginx configuration file for your app:

nano /etc/nginx/conf.d/nextjs-app.conf

Paste the following lines of code:

Need a fast and easy fix?
✔ Unlimited Managed Support
✔ Supports Your Software
✔ 2 CPU Cores
✔ 2 GB RAM
✔ 50 GB PCIe4 NVMe Disk
✔ 1854 GeekBench Score
✔ Unmetered Data Transfer
NVME 2 VPS

Now just $43 .99
/mo

GET YOUR VPS
server {
listen 80;
server_name yourdomainhere.com

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;
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;
}
}

Save the file, close it, and check the Nginx configuration:

nginx -t

If everything is OK, you should see the following output:

root@host:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful	

Restart the Nginx service.

systemctl restart nginx

That’s it. You can successfully access your NextJS application in the browser at http://YourDomainNameHere.

Next.js

You Managed to Deploy Next.JS on Ubuntu 26.04

If you are not familiar with Ubuntu 26.04 or need help with the installation, don’t worry. Simply choose one of our NVMe VPS plans and submit a support ticket. Our administrators are available 24/7 to help you with the installation and configuration of Next.js on your server.

If you liked this post on how to deploy Next.js on Ubuntu 26.04, please share it with your friends or leave a comment below

Leave a Comment