Deploy (Multiple) Next.js Apps on Ubuntu (with Nginx)

Abdullah Ilgaz
7 min readJan 16, 2023

--

This guide will show you how to deploy a Next.js app on Ubuntu 18.04 (64 Bit) with Nginx.

Prerequisites

  • A domain name
  • A fresh Ubuntu 18.04 (64 Bit)
  • A user with sudo privileges

Step 1 — Update your system

First, we need to make sure that our system is up to date.

sudo apt update && sudo apt upgrade
sudo apt update && sudo apt upgrade

Step 2 — Install Nginx, Certbot and Python3-Certbot-Nginx

Next, we need to install Nginx, Certbot and Python3-Certbot-Nginx.

sudo apt install nginx certbot python3-certbot-nginx
sudo apt install nginx certbot python3-certbot-nginx

Step 3 — UFW Firewall Configuration

Now, we need to configure the UFW firewall.

sudo ufw allow 'Nginx Full'
sudo ufw allow ‘Nginx Full’

Step 4 — Allow OpenSSH

OpenSSH is the default SSH server on Ubuntu. We need to allow it in the firewall.

ufw allow OpenSSH
ufw allow OpenSSH

Step 5 — Enable Firewall

Now, we need to enable the firewall.

ufw enable
ufw enable

Step 6 — Install NPM

Next, we need to install NPM

apt install npm
apt install npm

We can check our Ubuntu Nginx default page by visiting our domain name in the browser.

Nginx Default Page

Step 7 — Install PM2

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

npm install pm2 -g
npm install pm2 -g

If you get an error for your Node.js version, you can update it with the following command:

curl -fsSL https://deb.nodesource.com/setup_16.x | sudo -E bash -

Then, you can install Node.js with the following command:

sudo apt install -y nodejs

Now, you can install PM2 again.

Step 8 — Install NVM and Node.js

Change directory to /var/www and list the files.

cd /var/www
ls
cd /var/www

NVM is a Node.js version manager. It allows you to install multiple Node.js versions and switch between them.

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

Reload your shell.

exec $SHELL

Then, install nvm.

nvm install --lts
nvm install — lts

If you get an error for your Node.js version, you can change it to 16 with the following command:

nvm install 16

Step 9 — Create a Next.js App

Create a Next.js app with the following command:

npx create-next-app@latest ubuntu-next-app

If you get versionGLIBC_2.28' not found` error, then you can change your Node.js version to 16 with the following command:

nvm install 16
npx create-next-app@latest ubuntu-next-app

I prefer TypeScript, so I will choose Yes for the Would you like to use TypeScript with this project? question.

Also Yes for the Would you like to add ESLint to your project? question.

Here is the rest of the questions:

rest of the questions

Success! Created ubuntu-next-app at /var/www/ubuntu-next-app

Success! Created ubuntu-next-app

Change directory to ubuntu-next-app and npm install with run build command.

cd ubuntu-next-app
npm run build
npm run build

Step 10 — Configure Nginx

Change directory to sites-available and list the files.

cd /etc/nginx/sites-available
ls
cd /etc/nginx/sites-available

Create a new file and name it ubuntu-next-app. Then, open it with nano.

touch ubuntu-next-app
nano ubuntu-next-app

Then, copy and paste the following config into the file.

server {
listen 80;
server_name ubuntu-next-app.abdullahilgaz.com; # !!! - change to your domain name
gzip on;
gzip_proxied any;
gzip_types application/javascript application/x-javascript text/css text/javascript;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_min_length 256;

location /_next/static/ {
alias /var/www/ubuntu-next-app/.next/static/; # !!! - change to your app name
expires 365d;
access_log off;
}

location / {
proxy_pass http://127.0.0.1:3000; # !!! - change to your app port
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;
}
}

Now, save (ctrl+o) and exit (ctrl+x).

Time to enable the site. Go back to /etc/nginx/ and list the files.

cd /etc/nginx/ or cd ..
ls
nano ubuntu-next-app

We need to update the nginx.conf file. Open it with nano.

nano nginx.conf
        ##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*; # !!! - find this line
        ##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-available/*; # !!! - change to this line

Now, save (ctrl+o) and exit (ctrl+x).

Restart Nginx and check the syntax.

systemctl restart nginx
nginx -t
systemctl restart nginx && nginx -t

Clearing sites-enabled and sites-available directories.

cd sites-available
rm default
cd ..
cd sites-enabled
rm default

Restart Nginx again.

systemctl restart nginx

Step 11 — Configure PM2

Change directory to /var/www/ubuntu-next-app and list the files.

cd /var/www/ubuntu-next-app

Start the app with PM2.

pm2 start npm --name "ubuntu-next-app" -- start
pm2 start npm — name “ubuntu-next-app” — start

Step 12 — SSL Certificate

Domain and DNS Configuration

Before we install ssl certificate to our domain, be sure that you have a domain name and it is pointing to your server.

In this guide, I will use ubuntu-next-app.abdullahilgaz.com, a subdomain for my domain name. So, you need to change the domain name to your own domain name.

I’m using Cloudflare for my domain name. So, I will show you how to add a A record to Cloudflare.

Login to your Cloudflare account, choise your domain name and go to DNS tab. Then, click Add record button.

Basically, you need to add a A record to your domain name.

Name: ubuntu-next-app (your subdomain name)
IP Address: your server ip address

Click Save button.

Cloudflare DNS Management

SSL Installation with Certbot

Certbot is a free, open source software tool for automatically using Let’s Encrypt certificates on manually-administrated websites to enable HTTPS.

Now we install ssl certificate with certbot to our domain.

sudo certbot --nginx -d ubuntu-next-app.abdullahilgaz.com

Select 2 for Redirect - Make all requests redirect to secure HTTPS access.

sudo certbot — nginx -d ubuntu-next-app.abdullahilgaz.com

Restart Nginx.

systemctl restart nginx

Check our domain with https.

https://ubuntu-next-app.abdullahilgaz.com

Yahoo! It’s working!

Now we change a little bit our index.tsx file. Open it with nano.

nano pages/index.tsx
nano pages/index.tsx

To apply the changes, we build the app again.

npm run build
https://ubuntu-next-app.abdullahilgaz.com

Step 13 — Create second Next.js App

Go back to /var/www and create a new Next.js App. Then, change directory to the app and build it.

cd /var/www
npx create-next-app second-app
cd second-app
npm run build

Now, we need to create a new config file for our second app. Go back to /etc/nginx/sites-available and create a new file. Then, open it with nano.

cd /etc/nginx/sites-available
touch second-app
nano second-app

Then, copy and paste the following config into the file.

server {
listen 80;
server_name second-app.abdullahilgaz.com;
gzip on;
gzip_proxied any;
gzip_types application/javascript application/x-javascript text/css text/javascript;
gzip_comp_level 5;
gzip_buffers 16 8k;
gzip_min_length 256;
location /_next/static/ {
alias /var/www/second-app/.next/static/;
expires 365d;
access_log off;
}
location / {
proxy_pass http://127.0.0.1:3001; # !!! This time, we use port 3001
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;
}
}

Now, save (ctrl+o) and exit (ctrl+x).

Go to /var/www/second-app and open package.json file with nano.

cd /var/www/second-app
nano package.json

Then, change the start script to "start": "next start -p 3001". Now, save (ctrl+o) and exit (ctrl+x).

{
"name": "second-app",
"version": "0.1.0",
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start -p 3001" # !!! This time, we use port 3001
},
"dependencies": {
"next": "latest",
"react": "latest",
"react-dom": "latest"
}
}
nano package.json

Rebuild the app and start it with PM2.

npm run build
pm2 start npm --name "second-app" -- start

We can check pm2 status with pm2 status command.

pm2 status

Time to install ssl certificate to our second app.

sudo certbot --nginx -d second-app.abdullahilgaz.com

Select 2 for Redirect - Make all requests redirect to secure HTTPS access.

https://second-app.abdullahilgaz.com

Congratulations! You have successfully installed two Next.js apps on Ubuntu 18.04 server.

--

--

Abdullah Ilgaz

Muslim • Enthusiast • Serverless Developer • Code Artisan • MVP • fullstack, serverless, aws, dotnet, typescript, reactjs, nextjs