Inside Nginx

- ๐Ÿ‘จโ€๐Ÿ’ป Shrawan Poudel

  • pronounced like "engine-ex"
  • open source ?
    • Where does nginx Plus lie ?
  • asynchronous, event-driven approach
  • web server?
    • reverse proxy
    • HTTP cache
    • Load Balancer
    • Web Sockets
    • and many more ...

Am i only using Nginx?

No

  • Insight Workshop
  • CloudFlare
  • Adobe
  • NASA
  • ....[Truncated a very long list]

https://www.nginx.com/success-stories/ https://stack.g2.com/nginx

Lets Dive [nginx open source]

~ apt-get install nginx
# or any way you like ๐Ÿ˜›

Master and Worker Processes

  • one master and one more more worker
  • worker_processes directive in nginx.conf

Controlling NGINX

~ nginx -s SIGNAL_LISTS

  • quit
  • reload
  • stop
Configs

~ cat /etc/nginx/nginx.conf

Top level directives (contexts)
  • events - General connection processing
  • http - HTTP Traffic
  • mail - Mail Traffic
  • steam - TCP /UDP Traffic
Virtual Servers

use : server block


http {
        # Configuration specific to
        # HTTP and affecting all virtual servers
        server {
            # configuration of TCP virtual server 1
        }
        server {
            # configuration of TCP virtual server 2
        }
}
                
Inheritance?
Test and Reload

~ nginx -s reload

Oops!! Forgot to Test
I missed , but dont you miss it ๐Ÿค

~ nginx -t

Webserver

Serving static content


server {
        server_name
        listen 80;
        root
        location
}

location /static/ {
        # just do anything โ˜บ๏ธ
}
location /media/ {
        # just do anything โ˜บ๏ธ
}
                
404 and autoindex in directory

~ ls /home/static/
     - ok.html

# nginx server block
server  {
    root /home/static/;
    location / {
    }
}

~ curl yourdomain.com/
    - Got a 404 ?

                

server  {
        root /home/static/;
        location / {
           autoindex on;
        }
}
                

Got a auto generated directory listing ? Cool ๐Ÿ˜Ž

Ok , That was cool , But shouldn't i be able to create a custom index ? ๐Ÿ˜•

index to the rescue!!!


server  {
        root /home/static/;
        location / {
              index ok.html;
        }
}
                
root vs alias

server  {
        location /static-root/ {
                root /home/ubuntu/static-root/;
        }
        location /static-alias/ {
                alias /home/ubuntu/static-alias/;
         }
}
                
Contd .......

/static-root/
        - appends the location
        - full path : /home/ubuntu/static-root/static-root/
        - Correct it:
                - root /home/ubuntu/
/static-alias/
        - location parts get dropped
        - full path: /home/ubuntu/static-alias/
        - Bonus:
                Remember the trailing slash on alias

                
Trying Several Options

server {
    root /home/ubuntu/
    location /images/ {
          try_files $uri /images/default.gif;
    }
}
server {
       root /home/ubuntu/
       location / {
             try_files $uri $uri/ $uri.html =404;
       }
}
                
Can also redirect to named location

server {
    location / {
          try_files $uri $uri/ @backend;
     }

    location @backend {
          proxy_pass http://backend.example.com;
    }

}
                
Nginx Reverse Proxy
  • sends request to specified proxied server
  • fetches the response and sends back to client
  • Even to non-HTTP servers ๐Ÿ˜ฎ
  • Supported protocols
    • FastCGI
    • uwsgi
    • SCGI
    • memcached
  • Use proxy_pass directive
Contd....

location / {
    proxy_pass http://localhost:8085;
}
                

To pass a request to a non-HTTP proxied server, the appropriate **_pass directive should be used:

  • fastcgi_pass passes a request to a FastCGI server
  • uwsgi_pass passes a request to a uwsgi server
  • scgi_pass passes a request to an SCGI server
  • memcached_pass passes a request to a memcached server
uwsgi with Nginx
Passing Request Headers
  • Redefines two header fields
    • Host --> $proxy_host
    • Connection -> close
    Nginx gets rid of any empty headers
  • Nginx, by default, will consider any header that contains underscores as invalid
    • use underscores_in_headers directive to โ€œonโ€
Setting or Resetting Headers

use proxy_set_header


proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "";
                
You forgot me ๐Ÿ˜ฅ
Sorry !!
but, what ? ๐Ÿค”
proxy_bind

location / {
     proxy_bind 127.0.0.2;
     proxy_pass http://example.com/;
}

                
Compression and Decompression
  • Reduces size of transmitted data
  • But because of ,Runtime compression,can affect performance
  • set directive gzip to "on"
  • By default, NGINX compresses responses only with MIME type text/html
  • Add additional types
    • gzip_types text/plain application/xml;
Restricting Access by IP

use of allow or deny directive


location /api {
     #...
     deny  192.168.1.2;
     allow 192.168.1.1/24;
     allow 127.0.0.1;
     deny  all;
}
            
Note the Order of allow and deny directive
HTTP Load Balancing

Group the servers with upstream directive


upstream backend {
         server backend1.example.com;
         server backend2.example.com;
         server 192.0.0.1;
}
server {
       location / {
           proxy_pass http://backend;
       }
}
            

Load balancing Method

  • Round Robin (default)
  • Least Connections
    • least_conn;
  • IP Hash
    • ip_hash;
Something More !! ๐Ÿ˜
  • Sever weights
    (server backend1.example.com weight=5;)
  • Sever Slow -Start
    (server backend1.example.com slow_start=30s;)
Logging

Nginx Error Log Severity Levels


- debug - Useful debugging information to help determine where the problem lies.
- info - Informational messages that arenโ€™t necessary to read but may be good to know.
- notice - Something normal happened that is worth noting.
- warn - Something unexpected happened, however is not a cause for concern.
- error - Something was unsuccessful.
- crit - There are problems that need to be critically addressed.
- alert - Prompt action is required.
- emerg - The system is in an unusable state and requires immediate attention.
                

Error Log

  • use directive error_log
  • defaults to: logs/error.log*
  • eg: error_log logs/error.log alert;
    • will log alert and emerg

Access Logs

  • NGINX writes information about client requests in the access log right after the request is processed
  • defaults to: logs/access.log*
  • eg: access_log /spool/logs/nginx-access.log;

Log Formats

use directive log_format

                    
log_format compression '$remote_addr - $remote_user [$time_local] '
                        '"$request" $status $body_bytes_sent '
                        '"$http_referer" "$http_user_agent" "$gzip_ratio"';
#Using this compression log format on access_logs
access_log /spool/logs/nginx-access.log compression;

                    
                
HTTPS !!!

You need SSL certificate!!


server {
access_log /home/ubuntu/logs/nginx_access.log;
error_log /home/ubuntu/logs/nginx_error.log;
server_name api.example.com;
location /static/ {
alias /home/ubuntu/static/;
}

if ($host !~* ^(api.example.com)$ ) {
return 444;
}

location / {
.........
proxy_pass http://127.0.0.1:8085;
.........
}

listen 443 ssl;
ssl_certificate SSL_CERTIFICATE_LOCATION;
ssl_certificate_key SSL_CERTIFICATE__KEY_LOCATION;
}
            
Shouldn't i redirect http to https automatically ? ๐Ÿ˜•

server {
    if ($host = api.example.com) {
        return 301 https://$host$request_uri;
    }
	listen 80;
	server_name api.example.com;
    return 404;
}
                
Any Questions
Let's Jump to Demo ๐Ÿ˜

Made with ๐Ÿ’œ by Shrawan
~ with help of

  • nginx official docs
  • reveal.js