Deploying a Next.js Application on ubuntu Using Nginx Nodejs Pm2

Atik Shahriar Ratul
11 min readOct 1, 2023

--

Next.js is a popular React framework for building server-rendered React applications with ease. In this tutorial, we’ll walk through deploying a Next.js application on a DigitalOcean droplet using Nginx as a reverse proxy. This step-by-step guide assumes you have a Next.js application ready to deploy and a DigitalOcean account.

Prerequisites

Step 1: Creating a DigitalOcean Droplet

We’ll be hosting our Next.js app on a DigitalOcean Droplet that we configure ourselves. Let’s create the Droplet now.

  • Log in to your DigitalOcean account and navigate to the Droplets section.
  • Click “Create Droplet.”
  • Choose the Ubuntu image (preferably the latest LTS version).
  • Select the desired droplet size according to your needs and budget.
  • Choose a datacenter region closest to your target audience for better performance.
  • Add your SSH keys for secure access to your droplet.
  • Choose a hostname for your droplet, which can be your domain name or any preferred name.
  • Click “Create Droplet.”
  • Create Droplet

Once the Droplet is created, note down the IP address assigned to it.

Step 2: Setting Up the Droplet

Now that we’ve created the droplet, we need to prepare it so that it can accept incoming connections and route those connections to our Next.js application.

SSH into your droplet using the IP address and the SSH key you provided during the droplet creation:

ssh root@<DROPLET_IP>

Update and upgrade the packages on the droplet:

sudo apt update && sudo apt upgrade -y

Install nginx for the server

sudo apt install nginx

Step 2 — Adjusting the Firewall

Before testing Nginx, the firewall software needs to be adjusted to allow access to the service. Nginx registers itself as a service with ufw upon installation, making it straightforward to allow Nginx access.

List the application configurations that ufw knows how to work with by typing:

sudo ufw app list

You should get a listing of the application profiles:

Output
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH

As demonstrated by the output, there are three profiles available for Nginx:

  • Nginx Full: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • Nginx HTTP: This profile opens only port 80 (normal, unencrypted web traffic)
  • Nginx HTTPS: This profile opens only port 443 (TLS/SSL encrypted traffic)

It is recommended that you enable the most restrictive profile that will still allow the traffic you’ve configured. Right now, we will only need to allow traffic on port 80.

You can enable this by typing:

sudo ufw allow 'Nginx HTTP'

You can verify the change by typing:

sudo ufw status

The output will indicated which HTTP traffic is allowed:

Output
Status: active

To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)

Checking your Web Server

At the end of the installation process, Ubuntu 20.04 starts Nginx. The web server should already be up and running.

We can check with the systemd init system to make sure the service is running by typing:

systemctl status nginx
Output
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2020-04-20 16:08:19 UTC; 3 days ago
Docs: man:nginx(8)
Main PID: 2369 (nginx)
Tasks: 2 (limit: 1153)
Memory: 3.5M
CGroup: /system.slice/nginx.service
├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─2380 nginx: worker process

As confirmed by this out, the service has started successfully. However, the best way to test this is to actually request a page from Nginx.

You can access the default Nginx landing page to confirm that the software is running properly by navigating to your server’s IP address. If you do not know your server’s IP address, you can find it by using the icanhazip.com tool, which will give you your public IP address as received from another location on the internet:

curl -4 icanhazip.com

You should receive the default Nginx landing page:

If you are on this page, your server is running correctly and is ready to be managed.

Managing the Nginx Process

Now that you have your web server up and running, let’s review some basic management commands.

To stop your web server, type:

sudo systemctl stop nginx

To start the web server when it is stopped, type:

sudo systemctl start nginx

To stop and then start the service again, type:

sudo systemctl restart nginx

If you are only making configuration changes, Nginx can often reload without dropping connections. To do this, type:

sudo systemctl reload nginx

By default, Nginx is configured to start automatically when the server boots. If this is not what you want, you can disable this behavior by typing:

sudo systemctl disable nginx

To re-enable the service to start up at boot, you can type:

sudo systemctl enable nginx

You have now learned basic management commands and should be ready to configure the site to host more than one domain.

Configuring Nginx For Nextjs

Nginx is the tool that will handle all the routing to our Next.js application. Create a new Nginx configuration file for your Next.js application:

sudo nano /etc/nginx/sites-available/nextjs

Paste the following configuration, replacing server_name with your domain name or droplet IP address:

server {
listen 80;
server_name YOUR_IP_ADDRESS;
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;
}
}

Save and close the file. Create a symbolic link to enable the configuration:

sudo ln -s /etc/nginx/sites-available/nextjs /etc/nginx/sites-enabled/

Test the Nginx configuration for any syntax errors:

sudo nginx -t

If the configuration test is successful, restart Nginx

sudo service nginx restart

Deploying the Next.js Application To Droplet

Next up, we’ll get a Next.js application onto the Droplet. There are many options to do this. most recommend is use any git

  1. Create an SSH key on the server, connect it to your GitHub account, and clone your repo

SSH back into your droplet:

ssh root@<DROPLET_IP>

Clone Next.js application

Clone over SSH

cd /var/www
git clone git@bitbucket.org:teamsinspace/documentation-tests.git name_if_you_want

Clone over HTTPS

cd /var/www
git clone https://username@bitbucket.org/teamsinspace/documentation-tests.git name_if_you_want

use any of as you can access

Navigate to the Next.js application directory:

cd nextjs

Need to Install Nodejs on Server you can install any way you want .

i will show Installing Node Using the Node Version Manager

This way of installing Node.js that is particularly flexible is to use nvm, the Node Version Manager. This piece of software allows you to install and maintain many different independent versions of Node.js, and their associated Node packages, at the same time.

To install NVM on your Ubuntu 20.04 machine, visit the project’s GitHub page. Copy the curl command from the README file that displays on the main page. This will get you the most recent version of the installation script.

Before piping the command through to bash, it is always a good idea to audit the script to make sure it isn’t doing anything you don’t agree with. You can do that by removing the | bash segment at the end of the curl command:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh

Review the script and make sure you are comfortable with the changes it is making. When you are satisfied, run the command again with | bash appended at the end. The URL you use will change depending on the latest version of nvm, but as of right now, the script can be downloaded and executed with the following:

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash

This will install the nvm script to your user account. To use it, you must first source your .bashrc file:

source ~/.bashrc

Now, you can ask NVM which versions of Node are available:

nvm list-remote
Output
. . .
v18.0.0
v18.1.0
v18.2.0
v18.3.0
v18.4.0
v18.5.0
v18.6.0
v18.7.0
v18.8.0
v18.9.0
v18.9.1
v18.10.0
v18.11.0
v18.12.0 (LTS: Hydrogen)
v18.12.1 (LTS: Hydrogen)
v18.13.0 (Latest LTS: Hydrogen)
v19.0.0
v19.0.1
v19.1.0
v19.2.0
v19.3.0
v19.4.0

It’s a very long list. You can install a version of Node by writing in any of the release versions listed. For instance, to get version v14.10.0, you can run:

nvm install v14.10.0

You can view the different versions you have installed by listing them:

nvm list
Output
-> v14.10.0
v14.21.2
default -> v14.10.0
iojs -> N/A (default)
unstable -> N/A (default)
node -> stable (-> v14.21.2) (default)
stable -> 14.21 (-> v14.21.2) (default)
. . .

This shows the currently active version on the first line (-> v14.10.0), followed by some named aliases and the versions that those aliases point to.

Note: if you also have a version of Node.js installed through apt, you may receive a system entry here. You can always activate the system-installed version of Node using nvm use system.

Additionally, there are aliases for the various long-term support (or LTS) releases of Node:

utput
lts/* -> lts/hydrogen (-> N/A)
lts/argon -> v4.9.1 (-> N/A)
lts/boron -> v6.17.1 (-> N/A)
lts/carbon -> v8.17.0 (-> N/A)
lts/dubnium -> v10.24.1 (-> N/A)
lts/erbium -> v12.22.12 (-> N/A)
lts/fermium -> v14.21.2
lts/gallium -> v16.19.0 (-> N/A)
lts/hydrogen -> v18.13.0 (-> N/A)

You can install a release based on these aliases as well. For instance, to install the latest long-term support version, hydrogen, run the following:

nvm install lts/hydrogen
Output
Downloading and installing node v18.13.0...
. . .
Now using node v18.13.0 (npm v8.19.3)

You can switch between installed versions with nvm use:

nvm use v14.10.0
Output
Now using node v14.10.0 (npm v6.14.8)
You can verify that the install was successful using the same technique from the other sections:
node -v
Output
v14.10.0

The correct version of Node is installed on your machine as expected. A compatible version of npm is also available.

Setup Application For Deployment

Go to project directory:

cd /var/www/nextjs

Install the application dependencies:

npm install

Deploying a Next.js Application on a DigitalOcean Droplet

By Chris Sevilleja on 3 Apr 2023

Next.js is a popular React framework for building server-rendered React applications with ease. In this tutorial, we’ll walk through deploying a Next.js application on a DigitalOcean droplet using Nginx as a reverse proxy. This step-by-step guide assumes you have a Next.js application ready to deploy and a DigitalOcean account.

Here’s an overview of the key resources you may need:

  1. Next.js - The official website of the Next.js framework.
  2. React - The official website of the React JavaScript library.
  3. DigitalOcean - Create a DigitalOcean account if you don’t have one already

Prerequisites

  • A Next.js application
  • A DigitalOcean account
  • A registered domain name (optional but recommended)
  • A local installation of Node.js and npm or yarn

Step 1: Creating a DigitalOcean Droplet

We’ll be hosting our Next.js app on a DigitalOcean Droplet that we configure ourselves. Let’s create the Droplet now.

  • Log in to your DigitalOcean account and navigate to the Droplets section.
  • Click “Create Droplet.”
  • Choose the Ubuntu image (preferably the latest LTS version).
  • Select the desired droplet size according to your needs and budget.
  • Choose a datacenter region closest to your target audience for better performance.
  • Add your SSH keys for secure access to your droplet.
  • Choose a hostname for your droplet, which can be your domain name or any preferred name.
  • Click “Create Droplet.”
  • Create Droplet

Once the Droplet is created, note down the IP address assigned to it.

Step 2: Setting Up the Droplet

Now that we’ve created the droplet, we need to prepare it so that it can accept incoming connections and route those connections to our Next.js application.

SSH into your droplet using the IP address and the SSH key you provided during the droplet creation:

ssh root@<DROPLET_IP>

Copy

Update and upgrade the packages on the droplet:

sudo apt update && sudo apt upgrade -y

Copy

Install the required packages:

sudo apt install -y nodejs npm nginx

Copy

Step 3: Configuring Nginx

Nginx is the tool that will handle all the routing to our Next.js application. Create a new Nginx configuration file for your Next.js application:

sudo nano /etc/nginx/sites-available/nextjs

Copy

Paste the following configuration, replacing server_name with your domain name or droplet IP address:

server {
listen 80;
server_name YOUR_IP_ADDRESS;
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;
}
}

Copy

Save and close the file. Create a symbolic link to enable the configuration:

sudo ln -s /etc/nginx/sites-available/nextjs /etc/nginx/sites-enabled/

Copy

Test the Nginx configuration for any syntax errors:

sudo nginx -t

Copy

If the configuration test is successful, restart Nginx:

sudo service nginx restart

Copy

Step 4: Deploying the Next.js Application

Next up, we’ll get a Next.js application onto the Droplet. There are many options to do this.

  1. Create an SSH key on the server, connect it to your GitHub account, and clone your repo
  2. Create a Next.js application on the Droplet

For this tutorial, we will be creating a brand new Next.js application in our Droplet.

SSH back into your droplet:

ssh root@<DROPLET_IP>

Copy

Create a new Next.js application and follow the prompts:

cd /var/www
npx create-next-app nextjs

Copy

Navigate to the Next.js application directory:

cd nextjs

Copy

Install the application dependencies:

npm install

If you have any environment File copy on server. example

cp .env.example .env

Build the Next.js application:

npm run build

Finally, start the Next.js application:

npm start

Your Next.js application is now deployed and accessible at your domain name or droplet IP address. To keep your application running in the background and automatically restart on crashes or server reboots, you should use a process manager like PM2.

Setting Up PM2 Process Manager

We ran npm start from within our Droplet. Sometimes this command may stop running for reasons like the server restarted or it needed to install updates. We will use a tool called PM2 to make sure that our Next.js application is always running. PM2 will even restart the Next.js application if it goes down.

To install PM2 globally on your droplet:

npm install -g pm2

Navigate to the Next.js application directory (if not already there):

cd /var/www/nextjs

Start the Next.js application using PM2:

pm2 start npm --name "nextjs" -- start

You can run on different port if you

 pm2 start npm --name "nextjs" -- start -- --port 4000

This command will start the Next.js application with the name “nextjs” using the npm start command. PM2 will automatically restart the application if it crashes or if the server reboots.

To ensure PM2 starts on boot, run:

pm2 startup

This command will generate a script that you can copy and paste into your terminal to enable PM2 to start on boot.

Save the current PM2 processes:

pm2 save

You have now successfully deployed a Next.js application on a DigitalOcean droplet using Nginx as a reverse proxy and PM2 as a process manager. Your application should be accessible at your domain name or droplet IP address.

Remember to configure your DNS settings if you are using a domain name. Point your domain’s A record to your droplet’s IP address to access the application using the domain name.

For improved security and SEO, consider setting up SSL certificates using Let’s Encrypt and enforcing HTTPS connections. Additionally, you can explore optimizing your Next.js application with caching and other performance improvements.

That’s it! You have successfully deployed your Next.js application on a DigitalOcean Droplet. Happy coding!

--

--