How to deploy a Next.js project on Ubuntu with NGINX

December 07, 2021

10 min read

views

Requirements

There are a few things you must have.

  • A Next.js project
  • VPS with Ubuntu 20.04
  • Minimal experience in the terminal
  • A domain (only required for NGINX proxy)

Prepare VPS for deployment

There are a extra steps that we must perform so we can properly deploy our Next.js project to our domain. This includes installing Node.js, installing NGINX and setting up the firewall.

Installing required packages

Node.js

To install Node.js there are few simple steps required. Get the Node.js install via Nodesource.

$
curl -sL https://deb.nodesource.com/setup_18.x -o nodesource_setup.sh

Run the Nodesource setup file to prepare the correct version of Node.js

$
sudo bash nodesource_setup.sh

Install Node.js from the installed Nodesource

$
sudo apt install nodejs -y

Verify installation:

$
node -v # 18.x.x

NGINX

NGINX will be used as a proxy to serve our Next.js project.

$
sudo apt install nginx -y

Firewall

We must set up a firewall to only allow certain ports on our VPS. We will only allow 22 for SSH, 80 for HTTP and 443 for HTTPS

sudo ufw allow ssh # 22
sudo ufw allow "Nignx Full" # 80 and 443

To verify this worked, you can run the following command

$
sudo ufw status

Firewall disabled?

If your firewall is disabled, you can run this simple command to enable it 👉
sudo ufw enable

Next.js project setup on a VPS

First, we must be logged into our VPS. We will clone the Next.js project from GitHub onto our VPS.

# replace this URL with your repo
git clone https://github.com/Dev-CasperTheGhost/nextjs-ts-eslint-template.git

Now we must install the dependencies

npm install
# OR
yarn

Once all the dependencies are installed, we can build the client so it is ready to be deployed.

npm run build
# OR
yarn build

Now we can start the project in the background using pm2.

If you don't have pm2 installed yet, see the following command 👉
sudo npm install --global pm2
# `run start` is the command that will be executed.
pm2 start npm --name my-project -- run start

This will have successfully started the project. You can verify this with pm2 logs or open the IP with the port in your browser.

NGINX configuration

Once we've installed all the required packages, we can configure NGINX to serve our Next.js project.

NGINX proxy setup

Start by opening the following file with a text-editor: /etc/nginx/sites-available/default. I will use nano for this.

$
nano /etc/nginx/sites-available/default

You might already see some configurations, you can safely remove this.

We can now start editing this file and add our own server block.

server {
  # the name of your domain, www is optional.
  server_name my-domain.com www.my-domain.com;

  location / {
    # this must stay localhost. The port must be the same as your Next.js project
    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;
  }

  # simple headers
  add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
  add_header X-XSS-Protection          "1; mode=block" always;
  add_header X-Frame-Options DENY always;

  # this will serve the project on port 80
  listen 80;
}

Once done editing, save and exit the editor and verify the config file with the following command:

$
nginx -t

You may have noticed that we are serving the project on port 80. This is fine for now, since we haven't installed our certificates yet. If you do not need a secure site, you can skip to #final-deployment-steps! Continue reading on how to install certificates with Certbot.

Installing certificates with Cerbot

Cerbot can be installed in many ways and on many machines with different configurations, therefore please follow Cerbot's installation guide.

After following Cerbot's instructions, you should verify if it changed the NGINX config, open the config file and see changes made.

$
nano /etc/nginx/sites-available/default

Now you should see that the server block will serve the project on port 443 (HTTPS)!

Final Deployment steps

As our last step, we must restart NGINX with this simple command:

$
sudo systemctl reload nginx

Now verify that all is running, head over to your domain and see the project in action 🎉!

The end

That's it! You've successfully set up NGINX on Ubuntu and deployed a Next.js project to it