Linode Tutorial Part 3: Setting Up a Domain, Ubuntu, and Nginx Reverse Proxy for Multiple Routes

Habibi Coding | حبيبي كودنق
Geek Culture
Published in
7 min readFeb 28, 2023
tutorial banner

In this Part 2 summary, we covered the following steps to set up our Ubuntu instance:

*) Updating our system packages
*) Adding a new sudo user
*) Installing Nginx
*) Setting up two NodeJS apps, one for Frontend and one for Backend.

For more details, follow the link to: Part 2.

Configure Nginx

In this section, we will configure Nginx to act as a reverse proxy, forwarding requests from the public IP address to the localhost servers listening on localhost:9090 and localhost:9091.

Connect again to your Ubuntu instance and see if you have thenginx.conf file with the following command:

cat /etc/nginx/nginx.conf
nginx.conf

Also, check out if you find the default config file by entering this command:

cat /etc/nginx/conf.d/default.conf
default.conf

Create a folder for your domain

sudo mkdir -p /var/www/{your-domain}/
domain folder

Change ownership:

sudo chown -R $USER:$USER /var/www/{your-domain}/
change ownership

Change permissions:

sudo chmod -R 755 /var/www/{your-domain}/
change permissions

Create sites-available/ directory:

sudo mkdir /etc/nginx/sites-available/
create folder sites-available/

Create sites-enabled directory:

sudo mkdir /etc/nginx/sites-enabled
create folder sites-enabled/

Create your first server block

Enter the following command:

sudo vim /etc/nginx/sites-available/{your-domain}
create server block

Add the following config:

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name {your-domain} www.{your-domain};

location / {
# Frontend application
proxy_set_header Host $host;
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;

proxy_pass http://localhost:9091;
}

location /api/ {
# Backend application
proxy_set_header Host $host;
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;

proxy_pass http://localhost:9090;
}
}
your domain file

proxy_set_header Host $host: Preferred over proxy_set_header Host $prox_host as you don’t need to explicitly define proxy_host and it’s accounted for by default. $host contains the following: request line hostname or a Host header field hostname (source: Linode).

proxy_set_header X-Real-IP $remote_addr: Send the visitors IP address to our proxy server (source: Linode).

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for: This is a list of IP addresses of servers that every client was served a proxy from (source: Linode).

proxy_set_header X-Forwarded-Proto $scheme: Sets the X-Forwarded-Proto header in the request that is being sent to the backend server. The $scheme variable holds the value of the protocol (either http or https) that the client used to connect to the Nginx server. By setting the X-Forwarded-Proto header, the backend server can use the information to determine the protocol that was used by the client to reach Nginx. This can be useful in a number of situations, such as when the backend server needs to redirect the client to a secure (HTTPS) connection or when it needs to generate URLs with the correct scheme in response headers or in the HTML document (source: Linode).

proxy_pass: Is the revere proxy function.

Next, open the main Nginx config file with this command:

sudo vim /etc/nginx/nginx.conf
edit nginx.conf

Include at the bottom of the file sites-enabled directory

include /etc/nginx/sites-enabled/*;
include /etc/nginx/sites-enabled/*;

Create a symlink for your domain folder:

sudo ln -s /etc/nginx/sites-available/{your-domain} /etc/nginx/sites-enabled/
soft link

Testing the config

Now, check if still everything is okay by entering:

sudo nginx -t
sudo nginx -t

It is important to see “syntax is ok” and “test is successful”.

Then reload the Nginx config:

sudo nginx -s reload
Nginx reload

Start the NodeJS applications:

First, start the Backend:

cd node_backend_app/ && nohup node app.js &
start backend app

Then start the Frontend:

cd node_frontend_app/ && nohup node app.js &
start frontend app

Make sure both applications are running by installing net-tools

sudo apt install net-tools
net-tools

To see if they are running enter:

sudo netstat -tunlp
sudo netstat -tunlp

Open any web browser on your device and type the following URLs http://{your-domain}/api/ and http://{your-domain}//

{your-domain}/ && {your-domain}/api/

Setting up the Cert Bot — Yalla | يلا

As you can see our Frontend and Backend applications both run on plain HTTP not HTTPS. For a valid SSL certificate, we need Certbot.

Check if you have Snap installed:

snap version
apt policy snapd
snap check

If Snapd is not installed just type:

sudo apt install snapd
install snapd

Just to make sure everything went smoothly type this command to make sure that certbot-auto and any Certbot OS packages are removed:

sudo apt-get remove certbot
remove Certbot packages

Now install Certbot:

sudo snap install --classic certbot
install Certbot

Prepare Certbot with this command:

sudo ln -s /snap/bin/certbot /usr/bin/certbot
softlink for Certbot

Check if the soft link really got set by typing:

which certbot
validating softlink

Check if Certbot got really installed:

sudo certbot --version
Certbot version

Run a test to see if Certbot properly works:

sudo certbot --nginx --test-cert
install test certificate
success messages

If you saw the success messages at the end, then request the real certificates:

sudo certbot --nginx
install real SSL certificate

Press Enter for all options:

choose all options

Because we have installed test certificates this question shows up now, just press: 2 + Enter

replace test certificate
successfully received certificate

Test automatic renewal

The Certbot packages on your system come with a cron job or systemd timer that will renew your certificates automatically before they expire. You will not need to run Certbot again, unless you change your configuration. You can test automatic renewal for your certificates by running this command:

sudo certbot renew --dry-run
test auto renew

Open now a web browser to check if the connection to the applications is secure.

Frontend HTTPS
Backend HTTPS

Take a look now, at what Certbot did to your server blocks file:

cd /etc/nginx/sites-available/

Look at your domain file:

cat {your-domain}
cat command
server {
server_name {your-domain} www.{your-domain};

location / {
# Frontend application
proxy_set_header Host $host;
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;

proxy_pass http://localhost:9091;
}

location /api/ {
# Backend application
proxy_set_header Host $host;
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;

proxy_pass http://localhost:9090;
}

listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/{your-domain}/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/{your-domain}/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}
server {
if ($host = www.{your-domain}) {
return 301 https://$host$request_uri;
} # managed by Certbot


if ($host = {your-domain}) {
return 301 https://$host$request_uri;
} # managed by Certbot


listen 80 default_server;
listen [::]:80 default_server;
server_name {your-domain} www.{your-domain};
return 404; # managed by Certbot

}

Notice the comments: # managed by Certbot

And that's it for this tutorial series.

Congratulations | Mabrook | مبروك you have completed the ENTIRE TUTORIAL SERIES!!!

You should be proud of yourself! If you enjoyed this article, give it a clap.

Big shout out to certbot instructions &Anton Putra’s tutorial and his documentation on GitHub.

Also, please consider donating to the Certbot project by visiting the link: https://supporters.eff.org/donate/support-work-on-certbot.

You can also check out the article in video format on YouTube at: https://www.youtube.com/@habibicoding.

--

--