Deploy (Multiple) Next.js Apps on Ubuntu (with Nginx)
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
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
Step 3 — UFW Firewall Configuration
Now, we need to configure the UFW firewall.
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
Step 5 — Enable Firewall
Now, we need to enable the firewall.
ufw enable
Step 6 — Install NPM
Next, we need to install NPM
apt install npm
We can check our Ubuntu Nginx default page by visiting our domain name in the browser.
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
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
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
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 version
GLIBC_2.28' not found` error, then you can change your Node.js version to 16 with the following command:
nvm install 16
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:
Success! Created ubuntu-next-app at /var/www/ubuntu-next-app
Change directory to ubuntu-next-app and npm install with run build command.
cd ubuntu-next-app
npm run build
Step 10 — Configure Nginx
Change directory to sites-available
and list the files.
cd /etc/nginx/sites-available
ls
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
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
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
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.
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.
Restart Nginx.
systemctl restart nginx
Check our domain with https.
Yahoo! It’s working!
Now we change a little bit our index.tsx
file. Open it with nano.
nano pages/index.tsx
To apply the changes, we build the app again.
npm run build
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"
}
}
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.
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.
Congratulations! You have successfully installed two Next.js apps on Ubuntu 18.04 server.