NGINX is a web server designed for use cases involving high volumes of traffic. It’s a popular, lightweight, high-performance solution.
One of its many impressive features is that it can serve static content (media files, HTML) efficiently. NGINX utilizes an asynchronous event-driven model, delivering reliable performance under significant loads.
This web server hands dynamic content off to FastCGI, CGI, or alternative servers (including Apache), before it’s sent back to NGINX for delivery to clients.
NGINX, renowned for its lightweight architecture and efficient handling of high traffic, contrasts with Apache, a longstanding and widely-used web server. While Apache excels in versatility and compatibility with various modules and configurations, NGINX prioritizes speed and scalability, making it a preferred choice for modern web applications with heavy traffic loads. For a comprehensive analysis of NGINX’s advantages over Apache and their respective use cases, refer to our detailed guide on NGINX vs Apache.
In this guide on how to configure NGINX, we’ll explore the essentials of NGINX to help you understand how it works and what benefits it offers.
Key Takeaways
- NGINX is a highly efficient, open-source software used for serving web content and as a reverse proxy. It utilizes an asynchronous, event-driven approach that optimizes the handling of concurrent web requests without performance bottlenecks.
- Optimal NGINX server configuration involves setting up server blocks to handle different domains. It employs advanced location directives for request management and optimizing performance via worker processes, compression, and caching.
- Securing an NGINX server is critical. It involves configuring SSL/TLS, restricting access with authentication and IP address filtering, and regularly checking error logs, and addressing common configuration errors to maintain server integrity.
NGINX Configuration: Understanding Directives
Every NGINX configuration file will be found in the /etc/nginx/ directory, with the main configuration file located in /etc/nginx/nginx.conf .
NGINX configuration options are known as “directives”: these are arranged into groups, known interchangeably as blocks or contexts .
When a # appears before a line, these are comments and NGINX won’t interpret them. Lines that contain directives should end with a semicolon (;). If not, NGINX will be unable to load the configuration properly and report an error.
Below, we’ve included a shortened copy of the /etc/nginx/nginx.conf file included with installations from NGINX repositories. This file begins with four directives:
user
worker_processes
error_log
pid
These exist outside any particular context or block, and are said to be within the main context.
Additional directives are found within the events and http blocks, and these also exist within the main context.
File: /etc/nginx/nginx.conf
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
. . .
}
http {
. . .
}
What is the Http Block?
The http block includes directives for web traffic handling, which are generally known as universal . That’s because they get passed on to each website configuration served by NGINX.
File: /etc/nginx/nginx.conf
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
What are Server Blocks?
The http block shown above features an include directive. This informs NGINX where website configuration files can be found.
When installing from NGINX’s official repository, the line will read include /etc/nginx/conf.d/*.conf; just as you can see in the http block placed above. Every website hosted with NGINX should feature a unique configuration file in /etc/nginx/conf.d/, and the name will be formatted as example.com.conf.Those sites that have been disabled — not served by NGINX — should be titled example.com.conf.disabled.
When installing NGINX from the Ubuntu or Debian repositories, the line will read: include /etc/nginx/sites-enabled/*;. The ../sites-enabled/ folder will include symlinks to the site configuration files located within /etc/nginx/sites-available/. You can disable sites within sites-available if you take out the symlink to sites-enabled.
According to the installation source, an illustrative configuration file can be found at /etc/nginx/conf.d/default.conf or etc/nginx/sites-enabled/default.
No matter the installation source, though, server configuration files feature one or more server blocks for a site. As an example, let’s look at the below:
File: /etc/nginx/conf.d/example.com.conf
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html;
try_files $uri /index.html;
}
What are Listening Ports?
The listen directive informs NGINX of the hostname/IP and TCP port, so it recognizes where it must listen for HTTP connections.
The argument default_server means that this virtual host will be answering requests on port 80 which don’t match the listen statement of a separate virtual host. When it comes to the second statement, this will listen over IPv6 and demonstrate similar behavior.
What is Name-based Virtual Hosting?
The server_name directive enables a number of domains to be served from just one IP address, and the server will determine which domain it will serve according to the request header received.
Generally, you should create one file for each site or domain you wish to host on your server. Let’s delve into some examples:
Process requests for example.com and www.example.com:
The server_name directive can utilize wildcards. *.example.com and .example.com tell the server to process requests for all example.com subdomains:
File: /etc/nginx/conf.d/example.com.conf
server_name *.example.com;
server_name .example.com;
Process requests for all domain names starting with example.:
File: /etc/nginx/conf.d/example.com.conf
server_name example.*;
With NGINX, you can define server names that are invalid domain names: it utilizes the name from the HTTP header to answer requests regardless of whether the domain name is valid or invalid.
You may find non-domain hostnames helpful if your server is on a LAN or you know all the clients likely to make requests on the server. This encompasses front-end proxy servers with /etc/hosts entries set up for the IP address NGINX is listening on.
What are Location Blocks?
NGINX’s location setting helps you set up how NGINX responds to requests for resources inside the server. As the server_name directive informs NGINX how it should process requests for the domain, location directives apply to requests for certain folders and files (e.g. http://example.com/blog/.) .
Let’s consider a few examples:
File: /etc/nginx/sites-available/example.com
location / { }
location /images/ { }
location /blog/ { }
location /planet/ { }
location /planet/blog/ { }
These locations are literal string matches and match any part of an HTTP request following the host segment:
Request: http://example.com/
Returns: Let’s assume there’s a server_name entry for example.com. In this case, the location/directive determines what occurs with this request.
With NGINX, requests are always fulfilled with the most specific match possible:
Request: http://example.com/planet/blog or http://example.com/planet/blog/about/
Returns: This will be fulfilled by the location /planet/blog directive as it’s more specific, despite location /planet being a match too.
File: /etc/nginx/sites-available/example.com
location ~ IndexPage\.php$ { }
location ~ ^/BlogPlanet(/|/index\.php)$ { }
When location directives are followed by a ~ (tilde), NGINX performs a regular expression match, which is always case-sensitive.
For example, IndexPage.php would be a match with the first of the above examples, while indexpage.php wouldn’t.
In the second example, the regular expression ^/BlogPlanet(/|/index\.php)$ { } would match requests for /BlogPlanet/ and /BlogPlanet/index.php but not /BlogPlanet, /blogplanet/, or /blogplanet/index.php. NGINX utilizes Perl Compatible Regular Expressions (PCRE).
What if you prefer matches to be case-insensitive? You should use a tilde followed closely by an asterisk: ~*. You can see the above examples define that NGINX should process requests ending in a certain file extension: the first example determines that files ending in .pl, PL, .cgi, .perl, .Perl, .prl, and .PrL (as well as others) will all be a match for the request.
File: /etc/nginx/sites-available/example.com
location ^~ /images/IndexPage/ { }
location ^~ /blog/BlogPlanet/ { }
When you add a caret and a tilde (^~) to location directives, you’re informing NGINX that, should it match a particular string, it should stop searching for more specific matches and utilize these directives here instead.
Beyond this, these directives function as the literal string matches do in the first group. Even if a more specific match comes along at a later point, the settings will be utilized if a request is a match for one of these directives.
Now, let’s look at additional details on location directive processing.
File: /etc/nginx/sites-available/example.com
location = / { }
Finally, adding an equals symbol to the location setting forces an exact match with the requested path and ends up searching for more specific matches.
So, for example, the last example will be a match for http://example.com only, as opposed to http://example.com/index.html. If you use exact matches, you can enhance the speed of request times moderately. This can prove beneficial if certain requests are prevalent.
The processing of directives will follow this flow:
- Exact string matches will be processed first: NGINX stops searching if a match is located and will fulfill the request.
- Any remaining literal string directives will be processed next. NGINX will stop and fulfill a request if it finds a match using the ^~ argument. If not, NGINX will continue the processing of location directives.
- Each location directive with a regular expression (~ and ~*) will be processed next. If a regular expression matches the request, NGINX will end its search and fulfill the request.
- Finally, if there are no matching regular expressions, the literal string match that is most specific will be used.
Be sure that every file and folder found under a domain is a match for one or more location directives.
Nested location blocks are not recommended or supported.
How to Use Location Root and Index
The location setting is another variable with its own argument block.
When NGINX has identified the location directive that is the best match for a specific request, its response will be based on the associated location directive block’s contents. So, for instance:
File: /etc/nginx/sites-available/example.com
location / {
root html;
index index.html index.htm;
}
We can see, in this example, that the document root is based in the html/ directory. Under the NGINX default installation prefix, the location’s full path is /etc/nginx/html/.
Request: http://example.com/blog/includes/style.css
Returns: NGINX will try to serve the file found at /etc/nginx/html/blog/includes/style.css
Please note:
Absolute paths for the root directive can be used if you wish. The index variable informs NGINX which file it should serve if none are specified.
So, for instance:
Request: http://example.com
Returns: NGINX will try to serve the file found at /etc/nginx/html/index.html.
When a number of files are specified for the index directive, the list will be processed in order, and NGINX will fulfill the request with the first file found to exist. If index.html can’t be located in the relevant directory, index.htm will be utilized instead. A 404 message will be delivered if neither exists at all.
Let’s consider a more complex example that showcases several location directives for a server responding to the example domain:
File: /etc/nginx/sites-available/example.com location directive
location / {
root /srv/www/example.com/public_html;
index index.html index.htm;
}
location ~ \.pl$ {
gzip off;
include /etc/nginx/fastcgi_params;
fastcgi_pass unix:/var/run/fcgiwrap.socket;
fastcgi_index index.pl;
fastcgi_param SCRIPT_FILENAME /srv/www/example.com/public_html$fastcgi_script_name;
}
Here, we can see that the second location block handles all requests for resources ending in a .pl extension, and it specifies a fastcgi handler for them. NGINX will use the first location directive otherwise.
Resources are found on the file system at /srv/www/example.com/public_html/. When no exact file names are defined in the request, NGINX will search for the index.html or index.htm file and provide it. A 404 error message will be returned if zero index files are located.
Let’s consider what takes place during a number of example requests:
Request: http://example.com/
Returns: /srv/www/example.com/public_html/index.html if this exists. Otherwise, it will serve /srv/www/example.com/public_html/index.htm. And if both of these don’t exist, a 404 error will be provided.
Request: http://example.com/blog/
Returns: /srv/www/example.com/public_html/blog/index.html if this exists. If the file can’t be found because it doesn’t exist, a /srv/www/example.com/public_html/blog/index.htm will be served. If neither exists, NGINX will return a 404 error.
Request: http://example.com/tasks.pl
Returns: NGINX will take advantage of the FastCGI handler to execute the file found at /srv/www/example.com/public_html/tasks.pl and return the relevant result.
Request: http://example.com/username/roster.pl
Returns: NGINX will utilize the FastCGI handler to execute the file found at /srv/www/example.com/public_html/username/roster.pl and return the relevant result.
Conclusion
Mastering NGINX configuration is essential for optimizing web server performance and efficiently managing website resources. By understanding directives, blocks, and their implications, administrators can tailor NGINX to meet the demands of their specific use cases.
This guide provided a foundational understanding of NGINX configuration, empowering users to harness its capabilities effectively.
Efficient NGINX configuration is crucial for optimal server performance. Consider implementing NGINX performance-tuning techniques such as load balancing and caching in the HTTP block for even better scalability and responsiveness.
No comment yet, add your voice below!