require function in the above code. Within our server, we’ll render two different responses, depending on our current route. The two routes are /overview and /api.
On the /overview subdomain, we’ll render a plain text, while on the /api, we’ll render a JSON object. The above application will be accessed on the Public IPv4 address of your virtual machine — e.g., 34.211.115.4 on port 3000.
x@c7:/opt/nginx_server_project$ ls -l
total 8
-rw-r--r-- 1 root root 234 Jan 31 09:34 package.json
-rw-r--r-- 1 root root 542 Jan 31 09:54 server.js
x@c7:/opt/nginx_server_project$
Now that the Node server application is ready, let’s install Nginx and configure it.
x@c7:~$ cd /etc/nginx/sites-available
x@c7:/etc/nginx/sites-available$ sudo touch myserver.config
x@c7:/etc/nginx/sites-available$ sudo vi /etc/nginx/sites-available/myserver.config
x@c7:/etc/nginx/sites-available$
Paste in the following configuration:
#The Nginx server instance
server{
listen 80;
server_name wach.quest;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# location /overview {
# proxy_pass http://127.0.0.1:3000$request_uri;
# proxy_redirect off;
# }
}
}
The above configuration has Nginx listening on port 80 on your-domain.com. The / is your Uniform Resource Identifier (URI) with the following properties:
• proxy_set_header: Sets the host header to be that of the Nginx server
• proxy_pass HTTP: Instructs Nginx to proxy all requests matching the location pattern to an upstream (backend) server
•proxy_http_version: Converts the incoming connection to HTTP 1.1
• proxy_set_header Upgrade: Converts the proxied connection to type Upgrade because WebSockets only communicate on upgraded connections
•proxy_set_header Connection: Ensures the connection header value is Upgrade
Save the changes and exit the file by clicking the Esc key. Then, type the command :wq and hit the Enter or Return key.
Next enable the new config file in the sites-available directory with a symbolic link in the sites-enabled directory
x@c7:/etc/nginx/sites-available$ sudo ln -s /etc/nginx/sites-available/myserver.config /etc/nginx/sites-enabled/
x@c7:/etc/nginx/sites-available$
x@c7:/etc/nginx/sites-available$ ls -l /etc/nginx/sites-enabled
total 0
lrwxrwxrwx 1 root root 42 Jan 31 12:20 myserver.config -> /etc/nginx/sites-available/myserver.config
lrwxrwxrwx 1 root root 40 Jan 27 09:17 with-ssl.conf -> /etc/nginx/sites-available/with-ssl.conf
x@c7:/etc/nginx/sites-available$
Remove the symbolic link to the other configuration
x@c7:/etc/nginx/sites-available$ sudo unlink /etc/nginx/sites-enabled/with-ssl.conf
Change the permissions to the symbolic link
x@c7:/etc/nginx/sites-available$ sudo chmod 644 /etc/nginx/sites-enabled/myserver.config
x@c7:/etc/nginx/sites-available$ ls -l /etc/nginx/sites-enabled/
total 0
lrwxrwxrwx 1 root root 42 Jan 31 12:20 myserver.config -> /etc/nginx/sites-available/myserver.config
x@c7:/etc/nginx/sites-available$
Test the configuration
x@c7:/etc/nginx/sites-available$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
x@c7:/etc/nginx/sites-available$
Restart NginX
x@c7:/etc/nginx/sites-available$ sudo systemctl restart nginx
x@c7:/etc/nginx/sites-available$
Change to directory of Node.js application
x@c7:/etc/nginx/sites-available$ cd /opt/nginx_server_project
x@c7:/opt/nginx_server_project$
Start application
x@c7:/opt/nginx_server_project$ node server.js
Listening for request
Open a browser and access the Node.js application using the domain http://c7.xcvvc.com:
Access the /overview endpoint of the application http://c7.xcvvc.com/overview.
Test if the api is accessible http://c7.xcvvc.com/api.
Adding SSL/TLS encryption
Create a configuration file for port 443 traffic.
x@c7:~$ ls /etc/nginx/sites-available/
default myserver.config with-ssl.conf
x@c7:~$ sudo touch /etc/nginx/sites-available/nginx-443.config
[sudo] password for x:
x@c7:~$ sudo vi /etc/nginx/sites-available/nginx-443.config
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/de.somewhere.com.pem # /path/to/ssl_certificate.crt;
ssl_certificate_key /etc/ssl/private/c7.xcvvc.com.key # /path/to/ssl_certificate.key;
# SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
location / {
proxy_pass http://127.0.0.1:3000;
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;
}
}
Here is the list of configurations
x@c7:~$ ls -l /etc/nginx/sites-available/
total 16
-rw-r--r-- 1 root root 2815 Jan 27 09:01 default
-rw-r--r-- 1 root root 436 Jan 31 12:53 myserver.config
-rw-r--r-- 1 root root 602 Jan 31 16:25 nginx-443.config
-rw-r--r-- 1 root root 2817 Jan 18 22:56 with-ssl.conf
x@c7:~$
Add a 2nd symbolic link for the nginx-443.config file
x@c7:~$ sudo ln -s /etc/nginx/sites-available/nginx-443.config /etc/nginx/sites-enabled/
x@c7:~$ ls -l /etc/nginx/sites-enabled/
total 0
lrwxrwxrwx 1 root root 42 Jan 31 12:20 myserver.config -> /etc/nginx/sites-available/myserver.config
lrwxrwxrwx 1 root root 43 Jan 31 17:12 nginx-443.config -> /etc/nginx/sites-available/nginx-443.config
x@c7:~$
Check the nginx configuration
x@c7:~$ sudo nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
x@c7:~$
Restart NginX with the added configuration
x@c7:~$ sudo systemctl restart nginx
x@c7:~$
Open a browser and test the three categories using secure https://
A static server page: https://c7.xcvvc.com
An Overview page from node.js: https://c7.xcvvc.com/overview
A look at a node.js .api request: https://c7.xcvvvc.com/api
Load Balancing with NginX
From the end of the logrocket blog:
As Node.js applications develop in size to accommodate an increasing number of users, it becomes important to allocate incoming traffic among several backend servers to guarantee efficiency and dependability.
Nginx provides a variety of algorithms to help with load balancing. These algorithms determine how loads are distributed among the available servers:
http {
upstream node_app_servers {
# no load balancing method is specified for Round Robin
server api1.backend.com;
server api2.backend.com;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://node_app_servers;
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;
}
}
}
The upstream directive defines a group of backend Node.js servers for load balancing
Nginx distributes incoming requests among the specified servers using a default round-robin algorithm
The proxy_pass directive forwards requests to the backend servers within the upstream group
Another example from SSL-Dragon
Here is a brief description of installing ssl onto NginX from https://www.ssldragon.com/how-to/install-ssl-certificate/nginx/:
Edit the NGINX configuration file
Next, edit the NGINX configuration file. Add or edit the server block for HTTPS (port 443).
You will also need to include the following special properties:
listen 443 ssl; (for releases after 1.15.0)
ssl on; (for releases before 1.15.0)
ssl_certificate – pointed to the directory of your combined SSL file
ssl_certificate_key pointed to the directory of your private key file generated along with the CSR
The final version of your configuration file should look like the example below:
server {
listen 443 ssl;
#ssl on; (for releases before 1.15.0)
ssl_certificate /etc/ssl/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/ssl-dragon.key;
server_name ssl-dragon.com;
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
location / {
root /var/www/;
index index.html;
}
}
This is from "Beginning Node.js" p. 142. Listing 7-3 "1basic.js"
var express = require('express');
var serveStatic = require('serve-static');
var app = express()
.use(serveStatic(__dirname + '/public'))
.listen(3000);