Linode Tutorial Part 3: Setting Up a Domain, Ubuntu, and Nginx Reverse Proxy for Multiple Routes
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
Also, check out if you find the default config file by entering this command:
cat /etc/nginx/conf.d/default.conf
Create a folder for your domain
sudo mkdir -p /var/www/{your-domain}/
Change ownership:
sudo chown -R $USER:$USER /var/www/{your-domain}/
Change permissions:
sudo chmod -R 755 /var/www/{your-domain}/
Create sites-available/
directory:
sudo mkdir /etc/nginx/sites-available/
Create sites-enabled
directory:
sudo mkdir /etc/nginx/sites-enabled
Create your first server block
Enter the following command:
sudo vim /etc/nginx/sites-available/{your-domain}
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;
}
}
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
Include at the bottom of the file sites-enabled
directory
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/
Testing the config
Now, check if still everything is okay by entering:
sudo nginx -t
It is important to see “syntax is ok” and “test is successful”.
Then reload the Nginx config:
sudo nginx -s reload
Start the NodeJS applications:
First, start the Backend:
cd node_backend_app/ && nohup node app.js &
Then start the Frontend:
cd node_frontend_app/ && nohup node app.js &
Make sure both applications are running by installing net-tools
sudo apt install net-tools
To see if they are running enter:
sudo netstat -tunlp
Open any web browser on your device and type the following URLs http://{your-domain}/api/ and http://{your-domain}//
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
If Snapd is not installed just type:
sudo apt 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
Now install Certbot:
sudo snap install --classic certbot
Prepare Certbot with this command:
sudo ln -s /snap/bin/certbot /usr/bin/certbot
Check if the soft link really got set by typing:
which certbot
Check if Certbot got really installed:
sudo certbot --version
Run a test to see if Certbot properly works:
sudo certbot --nginx --test-cert
If you saw the success messages at the end, then request the real certificates:
sudo certbot --nginx
Press Enter
for all options:
Because we have installed test certificates this question shows up now, just press: 2 + Enter
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
Open now a web browser to check if the connection to the applications is secure.
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}
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.