A web server receives an HTTP request and returns the requested page. Nginx, created by Igor Sysoev in 2004, was built on what other servers like Apache did badly: performance, light weight, and high connection concurrency.
For what follows, you need Nginx installed on your machine. If you don't have it, you can install it by following this tutorial.
Configuration
Configuring Nginx comes down to creating a set of virtual servers that handle requests for particular domains or IP addresses. Each virtual server has its own configuration defining how it handles a request. Typically when you want to redirect to another server or rewrite a URL.
You define these configurations with what's called a directive, which we'll look at below.
The Nginx configuration lives in the /etc/nginx directory. That directory holds several files, but the ones we care about are:
nginx.conf: holds the general configuration.conf.d/andsites-enabled/: hold the configuration of the different servers.
You can put the configuration of all your servers in nginx.conf,
but to stay organized it's better to create one configuration file per
server in conf.d or sites-enabled.
Virtual server
A virtual server is defined in a server directive inside the http context, like this:
http {
# Configuration of server 1
server {}
# Configuration of server 2
server {}
}The http directive tells us we're in the configuration of a web server, not a mail server or anything else.
To tell your server which requests to listen for, use the listen directive with the IP address and port.
server {
#The server listens for requests arriving on IP 127.0.0.1 and port 8080
listen 127.0.0.1:8080;
}If you don't specify the port, the server listens on the "standard" port 80. And if you don't specify the address, the server listens on every address.
If several servers listen on the same IP address and port, Nginx tests the request's Host header against the value of the server_name directive to
work out which server matches. The value of server_name can be plain text, a wildcard, or a regular expression.
server {
#This server listens for requests with a Host of devlogger.net or www.devlogger.net
listen 80;
server_name devlogger.net www.devlogger.net;
}If several server names match the request's Host header, Nginx picks the most appropriate server by these steps:
- Exact name
- Longest wildcard starting with an asterisk, like
*.devlogger.net - Longest wildcard ending with an asterisk, like
devlogger.* - First matching regular expression (a regular expression has to start with a tilde ~)
If the request's Host header matches no server name, Nginx uses the default server. The default server is the
first server block in the nginx.conf file, unless you say so explicitly with the default_server parameter.
server {
listen 80 default_server;
#...
}Configuring locations
Once Nginx has decided which server takes a request, it tests the URI given in the request header against
the parameters of the location directives defined in the server block. The location directive defines how to handle
a request based on its URI.
You can define the location parameter in two different ways: prefix strings and a regular expression.
location /images/ {
#URIs like /images/hero.png are handled here
}
location ~ \.html?$ {
#The tilde ~ modifier means this is a regular expression
#URIs ending in .htm or .html are handled here
}Here's the selection process Nginx follows to choose a location:
- It tests the URI against all the prefix strings.
- If a location matches the URI exactly and also has the
=modifier, the search stops and Nginx takes that block. - Otherwise, if the best matching location has the
^~(caret-tilde) modifier, the regular expressions aren't checked. - Otherwise, Nginx remembers the location with the longest matching prefix string.
- Then it tests the URI against all the regular expressions.
- If a location matches the regular expression, the search stops and Nginx takes that location.
- Otherwise, if no regular expression matches, Nginx uses the location matching the prefix string it remembered (point 4).
Here are two uses of the location directive: serving static files, and acting as a proxy server.
server {
location /images/ {
#The "root" directive specifies the root directory for the request.
#If the URI is /images/hero.png, Nginx delivers the file at /data/hero.png.
root /data;
}
location / {
#The "proxy_pass" directive passes the request to the server given as a parameter.
proxy_pass http://other-server.com;
}
}Using variables
You can use variables in the Nginx configuration, and they're marked by a $ (dollar) at the start of the name. Nginx has predefined variables, such as those from its HTTP core, but you can also create your own variable for your own logic.
Returning specific HTTP response codes
Nginx can return a response directly, such as a redirect or a specific error.
location /not/found {
return 404;
}
location /old/url {
#Codes 301, 302, 303, and 307 require a second parameter, the redirect URL.
return 301 http://example.com/new/url;
}The return directive can go in the location or server block.
Error handling
With the error_page directive, Nginx can return a custom page with an HTTP error code when errors happen.
#Show the 404.html page when a 404 error happens
error_page 404 /404.html;URL rewriting
URL rewriting with Nginx happens directly in the server configuration. It's done with the rewrite directive, which can go
in the location or server block. A request's URI can go through several modifications while it's processed, and the directive takes two required
parameters and one optional parameter. The first parameter is the regular expression that has to match the request URI.
The second parameter is the URI that replaces the matched one. The third parameter is a flag that can interrupt the
rewrite processing, for example to make a redirect (301 or 302) or to stop other directives from running.
#The "break" flag means we stop the rewrite.
rewrite ^/post/(.*)$ /post?id=$1 break;
#The "last" flag means we stop the rewrite in the current server and location context,
#and Nginx passes the rewrite on to other locations again.
rewrite ^/tag/(.*)$ /tag?id=$1 last;Rewriting the HTTP response
Nginx can also rewrite the response before sending it to the client, through the sub_filter directive.
location / {
sub_filter 'href="http://127.0.0.1:8080/' 'href="https://$host/';
sub_filter 'img src="http://127.0.0.1:8080/' 'img src="https://$host/';
#The "sub_filter_once" directive tells Nginx to apply
#the "sub_filter" consecutively within a location.
sub_filter_once on;
}A response already modified by a sub_filter isn't replaced again if
another sub_filter match occurs.
