It is initially launched as an high performance web server, to server static content(HTML, images,..). Now It’s capabilities increased way more than and can be used as Reverse Proxy, Load Balancer, Mail Proxy and HTTP Caching

1. Running NGINX

  1. See AWS EC2 and launch an EC2 Instance, Make Sure there is an Default VPC is present
  2. SSH into instance through browser or through .pem file downloaded
  3. Run the Following commands
    • sudo apt update
    • sudo apt install nginx -y
    • sudo systemctl status nginx
  4. Open the public IPV4 address of the instance in browser, we should see the NGINX default page. If it’s not opening do this
    • Check whether It’s http or https, it should be http
    • Check the security groups, It should be SSH, HTTP, HTTPS all set to Anywhere IPV4

2. NGINX as a Web Server

  1. As we have our NGINX running from First Step. Let’s serve a sample HTML file via NGINX such that using it as an web server
  2. Let’s Understand some important files
    • /var/www/html - Default directory for static files
    • /etc/nginx/sites-available/default - Default config file pointing to the web root
  3. We have index.nginx-debian.html so it’s default serving it, Let’s create an index.html such that as per order it will serve index.html
    • Run this command echo "<h1>Hello from NGINX Web Server</h1>" | sudo tee /var/www/html/index.html
    • Reload nginx sudo systemctl reload nginx

Note:

  • Anatomy of Server Block
server {
        listen 80 default_server; # Listens on HTTP port 80
        listen [::]:80 default_server; #  Domain or IP to respond to
        root /var/www/html; # Path where NGINX looks for files
 
        index index.html index.htm index.nginx-debian.html; # Default file to serve - In order (usually index.html)
 
        server_name _;
 
        location / { # URL path handling
                try_files $uri $uri/ =404; # try files from uri if not found return 404 
        }
}
  • These two directives behave differently inside location blocks.
  1. root example:
location /static/ {
    root /data/www;
}
# /static/img.png → /data/www/static/img.png
  1. alias example
location /static/ {
    alias /data/www/;
}
# /static/img.png → /data/www/img.png
  • Serving HTML via Docker
  1. Create a project folder:
mkdir nginx-static && cd nginx-static
  1. Add index.html:
<!-- index.html -->
<h1>Hello from NGINX in Docker!</h1>
  1. Run NGINX Docker container:
docker run --name web-nginx -v $PWD:/usr/share/nginx/html:ro -p 8080:80 -d nginx
  1. Open in browser:
http://localhost:8080

3. NGINX as a Reverse Proxy

Instead of Sharing direct EC2 IP or DNS we will give NGINX DNS to the client and let them access via NGINX through this we achieve Rate Limiting, Web Application Firewall, Security, TLS, SSL comes out of the box with NGINX rather we configuring them manually

  1. Create/Import a Backend application and start the server
  2. add the below data into /etc/nginx/sites-available/default
location / {
    proxy_pass http://localhost:3000;        # server url
    proxy_set_header Host $host;             # host header
    proxy_set_header X-Real-IP $remote_addr; # client ip details
    try_files $uri $uri/ =404;               # 404 configuration
}
  1. Access the server IP and you will see the backend running
  2. check /var/log/nginx/access.log for request logs

4. NGINX as a Load Balancer

Uses NGINX to distribute traffic across multiple backend servers Create two servers running on port 3000 and 3001 and Edit /etc/nginx/sites-available/default with the below contents (Adding upstream block above the server conf) and check linting and reload the nginx conf using sudo nginx -t && sudo systemctl reload nginx and start servers using node index.js & node index1.js & not node index.js && node index1.js as it’s only runs server 1

  • round-robin - Default rotates through all backends equally
upstream backend_app {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
}
 
server {
    listen 80;
    server_name localhost;
    location / {
        proxy_pass http://backend_app; # change this to backend_app
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        try_files $uri $uri/ =404;      
    }
}
  • least_conn - Sends traffic to the backend with the fewest active connections
upstream backend_app {
    least_conn;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}
  • ip_hash - Uses client IP to consistently route requests to the same backend
upstream backend_app {
    ip_hash;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

5. Configuring HTTPS

Adding self signed certificate - Ideal for local development, If it’s public facing we need get SSL from external services

  1. Generate SSL certificate key
sudo openssl req -x509 -nodes -days 365 \
 -newkey rsa:2048 \
 -keyout /etc/ssl/private/nginx-selfsigned.key \
 -out /etc/ssl/certs/nginx-selfsigned.crt
  1. Add below configuration
server {
	listen 80 default_server;
    listen [::]:80 default_server;
    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;
    server_name _;
 
    listen 443 ssl;
    server_name localhost;
 
    ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
 
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}
 
# Optional: Redirect HTTP to HTTPS
server {
    listen 80;
    server_name localhost;
    return 301 https://$host$request_uri;
}
  1. Reload system configuration
sudo nginx -t
sudo systemctl reload nginx