Here is a list of frequently asked questions (FAQ) about NGINX:
NGINX is an open-source web server that can also function as a reverse proxy, load balancer, and HTTP cache. It’s known for its high performance, scalability, and ability to handle large numbers of concurrent connections.
While both are popular web servers, there are some key differences:
To install NGINX:
sudo apt update && sudo apt install nginx
sudo yum install nginx
brew install nginx
After installation, you can start NGINX using:
sudo systemctl start nginx
NGINX configuration files are usually located in /etc/nginx/nginx.conf
. Configuration can be broken into several blocks:
sudo systemctl restart nginx
sudo systemctl reload nginx
To set up NGINX as a reverse proxy, you need to edit the configuration file (/etc/nginx/sites-available/default
or /etc/nginx/nginx.conf
):
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
To enable HTTPS, you need an SSL certificate. You can get one for free from Let’s Encrypt or purchase one. After obtaining the certificate, modify your NGINX configuration to use it:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate /etc/ssl/certs/example.com.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
location / {
proxy_pass http://localhost:3000;
}
}
If using Let’s Encrypt, you can automate SSL management using the Certbot tool.
The default root directory where NGINX serves files from is typically /usr/share/nginx/html
or /var/www/html
, depending on the system.
You can use the limit_conn
and limit_req
modules to control the number of connections and requests:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
limit_conn addr 10;
limit_req_zone $binary_remote_addr zone=req:10m rate=1r/s;
}
You can enable stub_status for basic monitoring of active connections, requests, etc.:
server {
listen 80;
server_name localhost;
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
}
Tools like Grafana, Prometheus, or NGINX Amplify can provide more detailed monitoring and metrics.
You can block IPs by adding a deny rule in the server or location block:
server {
deny 192.168.1.1;
allow all;
}
NGINX supports several load-balancing methods (round-robin, least connections, etc.). Here’s a simple round-robin load balancing setup:
upstream backend {
server backend1.example.com;
server backend2.example.com;
}
server {
location / {
proxy_pass http://backend;
}
}
To handle CORS (Cross-Origin Resource Sharing) in NGINX, you can add headers in your server block:
server {
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'Origin, Authorization, Accept, Content-Type';
}
NGINX logs errors in the error log, typically located at /var/log/nginx/error.log
. You can adjust log levels (error, warn, info, debug) in your nginx.conf
file:
error_log /var/log/nginx/error.log warn;
NGINX uses worker processes to handle client requests. The number of worker processes can be set in nginx.conf
:
worker_processes auto;
Setting it to auto
usually works best as it automatically sets the number of workers to the number of CPU cores.
nano /etc/sysctl.conf
Append / modify the following line:
fs.file-max = 70000
Save and close the file. Edit /etc/security/limits.conf, enter:
nano /etc/security/limits.conf
Set soft and hard limit for all users or nginx user as follows:
nginx soft nofile 10000
nginx hard nofile 30000
Save and close the file. Finally, reload the changes with sysctl command:
sysctl -p
The following section provides a few examples of Nginx location blocks using a combination of modifiers and location match directives. These examples can be used in your own Nginx configuration and can be modified to suit your needs.
location = / {
# Only matches the / query.
}
location /data/ {
# Any query beginning with /data/ but the process continues searching.
# Will only be matched if regular expressions don’t find a match.
}
location ^~ /img/ {
# Queries beginning with /img/ and then stops searching.
}
location ~* .(png|gif|ico|jpg|jpeg)$ {
# Matches requests ending in png, gif, ico, jpg or jpeg.
# Any request to the /img/ directory are handled by the location block above.
}
Example how to prevent hotlinking of images:
location ~ .(png|gif|jpe?g)$ {
valid_referers none blocked yourwebsite.com *.yourwebsite.com;
if ($invalid_referer) {
return 403;
}
}
Reject scripts inside writable directories:
location ~* /(media|images|cache|tmp|logs)/.*.(php|jsp|pl|py|asp|cgi|sh)$ {
return 403;
}
No modifier at all means that the location is interpreted as a prefix. To determine a match, the location will now be matched against the beginning of the URI.
= The equal sign can be used if the location needs to match the exact request URI. When this modifier is matched, the search stops right here.
~ Tilde means that this location will be interpreted as a case-sensitive RE match.
~* Tilde followed by an asterisk modifier means that the location will be processed as a case-insensitive RE match.
^~ Assuming this block is the best non-RE match, a carat followed by a tilde modifier means that RE matching will not take place.
location ~ .flv$ {
flv;
}
location ~ .mp4$ {
mp4;
mp4_buffer_size 4M;
mp4_max_buffer_size 10M;
}
Directives explained:
flv; enables flv pseudostreaming.
mp4; enables mp4 pseudostreaming
mp4_buffer_size: the initial size of a memory buffer used for processing mp4 files.
mp4_max_buffer_size: needed to avoid error 500 while metadata file processing.
Important notes:
if mp4_max_buffer_size is set to a small size, you may get Internal Server error and a message like this:
“/myfile.mp4” mp4 moov atom is too large: 4758338, you may want to increase mp4_max_buffer_size
You may need to tweak client_max_body_size (and also php/nginx timeouts for very large files) option inside nginx.conf file to allow large file uploads, in my case I got it in this way:
client_max_body_size 80m;
proxy_set_header Accept-Encoding “”;
location / {
proxy_set_header Accept-Encoding “”;
proxy_pass http://localhost:8080/;
sub_filter “REPLACE” “WITHTTHIS”;
sub_filter_once off;
}