# NGINX basics with examples

### What is NGINX?

it is high performance web server used to serve static files like http and it also act as Reverse proxy, load balancer, http caching etc

### Why nginx, not httpd ?

* nginx is event driven architecture and httpd is thread based architecture
    
* nginx is simple and high performance
    
* low memory usage - become a choice for cloud native application
    
* Serves the static content very fast
    

Use official documentation to install nginx in your OS.

## NGINX and webserver

* webserver means is servers the static content that present in the file like html etc
    
* ```bash
    cd /etc/nginx #all nginx config files are present
    cd site-available/ #where we can add domain configuration files
    ```
    
* in site-available we can add domain specific configuration and if you need all site’s to be served in single domain we can use default file in that folder
    
* to create to domain specific file like example.com in the file update the configurations same as present in default file with different port number or root location and path to be servers etc
    
* after that we need to create symlink file in system enabled to serve that configuration file
    
* nginx.conf is the default config of nginx peferred to use the same if required we can modify as we required
    

## NGINX as Reverse Proxy

* After deploying the application and you provide the ip address of the application for accessing it, for that other then you client someone try to access it and may do some DDoS attack, can exceed rate limiting or may do vulnerability attack on your application so to avoiding that we need to handle all things in the application only (which is impossible due to some reasons) or they can use **Reverse proxy where client send the requests to reverse proxy instead of directly accessing the application they access the reverse proxy(nginx) that will forward our requests to application**
    
* Reverse proxy like nginx have advance capability to avoid DDoS attack by adding rate limiting, nginx can also implement WAF (web accessibility firewall), security related features like TLS, SSL. These are the in-built features in nginx so that it enough to develop only application from the developers
    
* Now let take simple node backend and add a nginx reverse proxy to it
    
    * Install the node and npm in the machine
        
    * and create a folder and create a server.js file init and add the below content inti
        
    * ```javascript
        const http = require('http');
        http.createServer((req, res) => {
          res.end('Hello from Node.js backend!');
        }).listen(3000);
        ```
        
    * ```bash
        node server.js #it will run the server and you can access the backed in port 3000
        ```
        
    * Now we can setup the reverse proxy
        
    * So, now go to folder /etc/nginx/sites-available/
        
    * edit the **default** file using vim editor (any other) and add the below code in location section
        
    * ```nginx
        location / {
            proxy_pass http://localhost:3000; #forward the request for path / to the provide address
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
        ```
        
    * ```bash
        sudo nginx -t #check the syntax error , id there is no error it will return OK
        sudo systemctl reload nginx #it will reload the nginx server
        ```
        
    * after all you can access the backed directly on IP no required of port
        
    * and make sure you are running the backed if not you will get “Bad Gateway” error
        

## NGINX as Load Balancer

* It is the process of distributing incoming traffic across the multiple servers
    
* Nginx will deal with multiple type of load balancer like round robin, weight based balancing, particular request based routing (IP based/ customer based)
    
* Steps to make nginx as load balancer as well as reverse proxy
    
    * Edit the `default` file present in `/etc/nginx/site-available/` folder. Add the below code just before the server block
        
        ```nginx
        upstream backend_app { #this is the block where you can add many servers that the traffic need to be forwarded
            server 127.0.0.1:3001 ;
            server 127.0.0.1:3002 ;
        }
        ```
        
    * And change the proxy\_pass address to the name of the upstream
        
        ```nginx
        location / {
            proxy_pass http://backend_app; #replace with upstream name
            proxy_set_header X-Real-IP $remote_addr;
        }
        ```
        
    * Now check the syntax and reload the nginx server
        
    * before testing run the application in both the port mentioned in upstream. you can run multiple servers by duplicating the same folder and change the port then run them with & symbol at last like below
        
        ```bash
        node server.js & #in 3001 port app folder
        node server.js & #in 3002 port app folder
        ```
        
    * Now you can test the application
        

### Different type of load balancer

* If we didn’t specify it then it is **Round Robin** Load balancing
    
* to change you can add extra line in upstream block as below
    
    ```nginx
    upstream backend_app { #this is the block where you can add many servers that the traffic need to be forwarded
        least_conn; #load balancing type least connection
        server 127.0.0.1:3001 ;
        server 127.0.0.1:3002 ;
    }
    ```
    
    ```nginx
    upstream backend_app { #this is the block where you can add many servers that the traffic need to be forwarded
        ip_hash; #load balancing type ip hash -> similar to sticky sesssion
        server 127.0.0.1:3001 ;
        server 127.0.0.1:3002 ;
    }
    ```
    

## NGINX with SSL or TLS (using self signed certificate)

* Self signed certificate only works on the machine where it is created or else you need to provide the certificate explicitly to open it in https
    
* Let create a certificate using `openssl` use below command
    
    ```bash
    sudo openssl req -x509 -nodes -days 365 \
     -newkey rsa:2048 \
     -keyout /etc/ssl/private/nginx-selfsigned.key \
     -out /etc/ssl/certs/nginx-selfsigned.crt
    ```
    
    the above command says that self signed certificate expires in 365 days & encryption type is RSA & location of the private key & location of the certificate
    
* The above command will ask some random questions fill them as below
    
* ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1755269497570/8c9eb3d6-97d4-4afa-8d12-cf788d75fa04.png align="center")
    
    where ever it ask for the common name please provide answer as `localhost` , you can change other questions as your requirement
    
* After that add the below code in **default** file present in **/etc/nginx/site-available/** folder
    
    ```nginx
    server {     
            #add the below config above the location block   
            listen 443 ssl ;
            server_name localhost;
            ssl_certificate /etc/ssl/certs/nginx-selfsigned.crt;
            ssl_certificate_key /etc/ssl/private/nginx-selfsigned.key;
    }
    
    # Optional: Redirect HTTP to HTTPS
    server {
        listen 80;
        server_name localhost;
        return 301 https://$host$request_uri;
    }
    ```
    
* So, you can test it only on your machine using `curl https://localhost -k` provide -k option or else it will ask you to provide the key for verification
