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
- See AWS EC2 and launch an EC2 Instance, Make Sure there is an
Default VPCis present - SSH into instance through browser or through .pem file downloaded
- Run the Following commands
sudo apt updatesudo apt install nginx -ysudo systemctl status nginx
- 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
- 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
- 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
- We have
index.nginx-debian.htmlso it’s default serving it, Let’s create anindex.htmlsuch that as per order it will serveindex.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
- Run this command
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
locationblocks.
rootexample:
location /static/ {
root /data/www;
}
# /static/img.png → /data/www/static/img.pngaliasexample
location /static/ {
alias /data/www/;
}
# /static/img.png → /data/www/img.png- Serving HTML via Docker
- Create a project folder:
mkdir nginx-static && cd nginx-static- Add
index.html:
<!-- index.html -->
<h1>Hello from NGINX in Docker!</h1>- Run NGINX Docker container:
docker run --name web-nginx -v $PWD:/usr/share/nginx/html:ro -p 8080:80 -d nginx- Open in browser:
http://localhost:80803. 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
- Create/Import a Backend application and start the server
- 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
}- Access the server IP and you will see the backend running
- check
/var/log/nginx/access.logfor 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
- 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- 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;
}- Reload system configuration
sudo nginx -t
sudo systemctl reload nginx