Getting Started with Nginx on Linux


๐Ÿ“˜ Section 1: Introduction to NGINX

โœ… What is NGINX?

NGINX is an open-source, high-performance web server that also functions as:

  • A reverse proxy
  • Load balancer
  • HTTP cache
  • Mail proxy

It is designed for high concurrency, performance, and low memory usage โ€” making it ideal for modern DevOps and cloud environments.


Reverse Proxy

nginx-reverse-proxy

๐Ÿ“Š NGINX vs Apache (Why DevOps Prefer NGINX)

FeatureNGINXApache
ArchitectureEvent-driven (asynchronous)Process/thread-based
PerformanceHigh concurrency, fastSlower with many connections
Memory usageLowHigh
Static contentExtremely fastGood
Config formatSimple, declarativeMore flexible but complex
Use casesWeb server, reverse proxy, LBTraditional web server

๐Ÿ’ก DevOps Engineers often choose NGINX for its:

  • Lightweight footprint
  • Ease of automation
  • Docker/Kubernetes friendliness

๐Ÿงฐ Common DevOps Use Cases for NGINX

Use CaseExample
Web serverServing static React/Angular apps
Reverse proxyForwarding requests to backend apps (Node.js, Python, Java)
Load balancerDistributing load between multiple backend servers
SSL terminationHandling HTTPS at the edge
CachingReducing load on upstream services
Ingress controller (Kubernetes)Managing traffic inside Kubernetes clusters
Rate limiting & security enforcementProtecting APIs from abuse or bots

๐Ÿ› ๏ธ Installing NGINX

๐Ÿง On Ubuntu/Debian

sudo apt update
sudo apt install nginx -y

๐Ÿ“ฆ On RHEL/CentOS

sudo yum install epel-release -y
sudo yum install nginx -y
docker run --name nginx -p 8080:80 -d nginx

Visit: http://localhost:8080


๐Ÿ“ NGINX File Structure (Linux)

File/DirectoryPurpose
/etc/nginx/nginx.confMain configuration file
/etc/nginx/sites-available/Stores virtual host (server block) configs
/etc/nginx/sites-enabled/Symlinks to active site configs
/var/www/htmlDefault web root directory
/var/log/nginx/Contains access and error logs

๐Ÿงช Demo: Run NGINX Using Docker

Step 1: Run container

docker run --name nginx-demo -p 8080:80 -d nginx

Step 2: Test in browser

Visit: http://localhost:8080
You should see the Welcome to NGINX page.

Step 3: View Logs

docker logs nginx-demo

Step 4: Clean up

docker stop nginx-demo
docker rm nginx-demo

๐ŸŒ Section 2: NGINX as a Web Server

๐Ÿš€ Goal

Learn how to use NGINX to serve static content such as HTML, CSS, JavaScript, and images โ€” a foundational skill for DevOps & Cloud Engineers.


๐Ÿง  What is a Web Server?

A web server is software that serves static files (like .html, .css, .js, .png) over HTTP.
When users visit your website, the web server responds with these files.

NGINX is one of the fastest and most popular web servers used for this purpose.


๐Ÿ“ Default Web Root in Linux

DirectoryPurpose
/var/www/htmlDefault directory for static files
/etc/nginx/sites-available/defaultDefault config file pointing to the web root

๐Ÿ“ Anatomy of a Basic server Block

server {
    listen 80;
    server_name localhost;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

Breakdown:

  • listen 80; โ†’ Listens on HTTP port 80
  • server_name localhost; โ†’ Domain or IP to respond to
  • root โ†’ Path where NGINX looks for files
  • index โ†’ Default file to serve (usually index.html)
  • location / โ†’ URL path handling

๐Ÿงช Demo: Serve a Static Website Using NGINX

๐Ÿ”ง Option 1: Using Native Linux NGINX

  1. Create an HTML file:
echo "<h1>Hello from NGINX Web Server</h1>" | sudo tee /var/www/html/index.html
  1. Reload NGINX:
sudo systemctl reload nginx
  1. Test: Visit: http://localhost or your serverโ€™s IP in browser.

๐Ÿณ Option 2: Serve HTML from 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

๐Ÿ”„ Root vs Alias

These two directives behave differently inside location blocks.

root example:

location /static/ {
    root /data/www;
}
# /static/img.png โ†’ /data/www/static/img.png

alias example:

location /static/ {
    alias /data/www/;
}
# /static/img.png โ†’ /data/www/img.png

๐Ÿ“Œ Use alias when you want to replace the URI path.


๐Ÿงฏ Common Errors & Fixes

ErrorSolution
403 ForbiddenCheck file permissions (use chmod/chown)
404 Not FoundEnsure correct root or alias
NGINX not reloading changesUse sudo nginx -s reload or restart NGINX
Port already in useUse sudo lsof -i :80 to identify process

๐Ÿ” Section 3: NGINX as a Reverse Proxy (Ubuntu/Linux)

๐Ÿง  What is a Reverse Proxy?

A reverse proxy is a server that receives client requests and forwards them to backend servers, then sends the response back to the client.

NGINX is one of the most popular tools used as a reverse proxy in production.


๐Ÿ”„ Reverse Proxy vs Forward Proxy

FeatureForward ProxyReverse Proxy
Who configures itClientServer-side
Forwards requests toExternal servers (internet)Internal backend servers (apps/services)
Use caseBrowsing anonymously, cachingLoad balancing, SSL termination, API gateway
ExampleProxy server for office usersNGINX between frontend and backend apps

๐Ÿ“Œ Why Use NGINX as a Reverse Proxy?

  • Protect backend services from direct access
  • Centralized SSL termination
  • Load balancing backend apps
  • Path-based routing (/api โ†’ backend1, /app โ†’ backend2)
  • Easy caching and compression

๐Ÿ“ Reverse Proxy Configuration (Ubuntu/Linux)

๐Ÿ”ง File: /etc/nginx/sites-available/default

Update the existing server block or create a new one:

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Breakdown:

  • proxy_pass โ†’ forwards requests to your backend app
  • proxy_set_header โ†’ preserves original request metadata (like IP and host)

๐Ÿงช Demo: Reverse Proxy to a Node.js App

Step 1: Install Node.js (optional if using your own backend)

sudo apt update
sudo apt install nodejs npm -y

Step 2: Create a simple backend app

mkdir ~/node-backend && cd ~/node-backend
nano server.js

Paste this:

const http = require('http');
http.createServer((req, res) => {
  res.end('Hello from Node.js backend!');
}).listen(3000);

Run it:

node server.js

Your app is now running at http://localhost:3000


Step 3: Configure NGINX as reverse proxy

Edit the NGINX default site:

sudo nano /etc/nginx/sites-available/default

Replace the location / {} block with:

location / {
    proxy_pass http://localhost:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Step 4: Test and reload NGINX

Check config for syntax errors:

sudo nginx -t

Reload NGINX:

sudo systemctl reload nginx

Step 5: Test in browser

Visit:

http://localhost

โœ… You should see: Hello from Node.js backend!


๐Ÿ“ File Structure Recap (Ubuntu)

PathPurpose
/etc/nginx/nginx.confGlobal NGINX settings
/etc/nginx/sites-available/defaultActive site config for reverse proxy
/var/www/htmlNot used in reverse proxy
/var/log/nginx/access.logLogs all requests

โš–๏ธ Section 4: Load Balancing with NGINX (Ubuntu/Linux)

๐ŸŽฏ Goal

Use NGINX to distribute traffic across multiple backend servers โ€” improving availability, reliability, and scalability of your applications.


๐Ÿง  What is Load Balancing?

Load balancing is the process of distributing incoming network traffic across multiple backend servers.

Benefits:

  • Prevents server overload
  • Increases availability and fault tolerance
  • Enables horizontal scaling

NGINX supports multiple load balancing algorithms out of the box.


๐Ÿงฎ Load Balancing Algorithms in NGINX

AlgorithmBehavior
round-robinDefault โ€” rotates through all backends equally
least_connSends traffic to the backend with the fewest active connections
ip_hashUses client IP to consistently route requests to the same backend

๐Ÿ“ Basic Load Balancer Configuration

Edit:

sudo nano /etc/nginx/sites-available/default

Replace contents with:

upstream backend_app {
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

server {
    listen 80;
    server_name localhost;

    location / {
        proxy_pass http://backend_app;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

๐Ÿงช Demo: Load Balance Two Local Backend Servers

Step 1: Create Backend Servers

Weโ€™ll run two simple HTTP servers using Node.js.

Create script:

mkdir ~/load-test && cd ~/load-test

server1.js

require('http').createServer((req, res) => {
  res.end('Response from Server 1');
}).listen(3001);

server2.js

require('http').createServer((req, res) => {
  res.end('Response from Server 2');
}).listen(3002);

Step 2: Run both servers

node server1.js &
node server2.js &

Step 3: Reload NGINX

sudo nginx -t
sudo systemctl reload nginx

Step 4: Test the Load Balancer

Open a browser or use curl:

curl http://localhost

Run it multiple times โ€” you should see the response alternate between:

Response from Server 1
Response from Server 2

โœ… Youโ€™ve just created a working load balancer using NGINX!


๐Ÿ”„ Switching Load Balancing Methods

Use Least Connections

upstream backend_app {
    least_conn;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

Use IP Hash

upstream backend_app {
    ip_hash;
    server 127.0.0.1:3001;
    server 127.0.0.1:3002;
}

๐Ÿ”’ Section 5: SSL/TLS Setup in NGINX Using a Self-Signed Certificate (Ubuntu/Linux)

๐ŸŽฏ Goal

Secure your application with HTTPS using a self-signed SSL certificate.
This is ideal for local development, internal tools, and non-public test environments.


๐Ÿง  Why Use HTTPS (Even in Dev)?

  • Encrypts traffic between client and server
  • Simulates production-like environment for testing
  • Helps catch mixed-content issues early
  • Required by modern frontend frameworks and APIs

๐Ÿ› ๏ธ Step-by-Step: Create a Self-Signed Certificate

Step 1: Generate SSL Certificate and 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

When prompted:

  • Common Name (CN): use localhost or your serverโ€™s IP

Step 2: Update NGINX Configuration

Edit the default site config:

sudo nano /etc/nginx/sites-available/default

Replace with the following:

server {
    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;
}

Step 3: Reload NGINX

Check and reload configuration:

sudo nginx -t
sudo systemctl reload nginx

Step 4: Test HTTPS Locally

Open your browser and visit:

https://localhost

โš ๏ธ You will see a warning:

โ€œYour connection is not privateโ€

โœ… Thatโ€™s expected with self-signed certs. Proceed anyway to view your site securely.


๐Ÿ“ SSL File Paths Recap

PathPurpose
/etc/ssl/certs/nginx-selfsigned.crtSSL certificate
/etc/ssl/private/nginx-selfsigned.keyPrivate key
/etc/nginx/sites-available/defaultHTTPS proxy config

๐Ÿงช Bonus: Test Without Browser (curl)

curl -k https://localhost

-k allows insecure (self-signed) HTTPS connections.


โœ… Summary

  • Self-signed SSL is perfect for secure local development.
  • Requires only OpenSSL and a few lines in NGINX.
  • Always test your HTTPS setup with curl and browser.
  • In production, switch to Letโ€™s Encrypt or trusted CAs.

๐ŸŽฏ Summary

  • NGINX is a lightweight, high-performance web server and reverse proxy.
  • Widely used in DevOps for load balancing, SSL termination, and as a reverse proxy.
  • Easy to install via Linux package managers or Docker.
  • Supports modular configuration โ€” great for automation and CI/CD.
  • NGINX can serve static files efficiently.
  • The root and index directives define where and what to serve.
  • Use Docker volumes to serve files without touching the host filesystem.
  • Always reload NGINX after making config changes.
  • NGINX can proxy traffic to backend apps using proxy_pass.
  • Config changes go in /etc/nginx/sites-available/default (on Ubuntu).
  • Always test config and reload NGINX after changes.
  • Ideal for API gateways, internal routing, and SSL termination.
  • Self-signed SSL is perfect for secure local development.
  • Requires only OpenSSL and a few lines in NGINX.
  • Always test your HTTPS setup with curl and browser.
  • In production, switch to Letโ€™s Encrypt or trusted CAs.