Nginx is a lightweight HTTP server and reverse proxy. It can also act as a load balancer, which is why it's often called an HTTP router.
It's a serious alternative to overloaded Apache. In a production environment, nginx impresses with its performance and low memory usage, which is an advantage for both large sites like wordpress.com and small ones like a weak 128MB VPS.
What works against nginx is the lack of .htaccess file support and the syntax of the rewrite module, which is somewhat different from the mod_rewrite syntax.
The lack of .htaccess support means that rewrite directives or other things normally handled in .htaccess must be introduced into the server configuration by its administrator.
The advantage nginx has over popular Apache comes from the model of handling incoming connections. In Apache, every new connection requires
starting a new process (mpm-prefork) or thread (mpm-worker) to handle the incoming request.
With nginx, we're dealing with an event-driven model where many connections are handled by the same process, which reacts to events such as a new request from a client,
a response from the application server, etc. If nothing is happening on one connection, the nginx process can handle another, active connection. An Apache process (thread) then waits idly.
Nginx creates 1-n... processes (depending on needs and hardware); each of these processes can handle several dozen/hundred thousand connections.
So much for the theory, in short.
At the outset, I want to note that I won't go into the process of installing nginx itself - as we know, that depends on the distribution (package) or an individual configuration (compiling from source).
- Global server configuration:
- main configuration file - nginx.conf
user www-data;
worker_processes 1;
error_log /var/log/nginx/error.log;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
sendfile on;
tcp_nopush on;
keepalive_timeout 0;
keepalive_timeout 65;
tcp_nodelay on;
gzip on;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
and a short description of this file:
Thanks to the two parameters above, we can theoretically estimate the maximum number of simultaneously served clients: max_clients = worker_processes * worker_connections , however keep in mind that when serving dynamic pages, e.g. in PHP, one client opens two connections (FastCGI), and then: max_clients = worker_processes * worker_connections / 2
and even more safely, divide by 4.
server {
# Directive specifying the address and/or port the server listens on
listen 80;
# Directive assigning names to virtual servers
server_name example.com www.example.com;
# Logs for the example.com domain
access_log /var/log/nginx/example.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
root path_to_our_site_directory;
index index.html index.htm;
}
}
# site_1:
server {
listen 80;
# ....
location / {
root /var/www/site_1;
index index.html index.htm;
}
}
# site_2:
server {
listen 81;
# ....
location / {
root /var/www/site_2;
index index.html index.htm;
}
}
While configuring nginx I ran into a rather troublesome situation. Let me present it with a concrete example:
Imagine we have the domain example.com, with 4 subdomains: main.example.com, mail.example.com, users.example.com, qwerty.example.com .
The first three are virtual hosts handled by nginx, while the last one, qwerty.example.com, is not associated with any
virtual host configuration. And here's where the problem appears - when we type http://qwerty.example.com/ into the browser, one
of these three sites will be displayed (probably depending on the order in which nginx does the includes).
In the nginx.conf file, we insert a server block before the include directives:
server {
listen 80 default;
server_name _ ; # Catch all
return 444; # Code 444 closes the connection without sending headers.
}
Of course, this is just a fraction of nginx's capabilities; I haven't mentioned anything about reverse-proxy configuration or its strong support for regular expressions...