A secure server is one that allows only as much as what is needed. Ideally, we would build a server based on a minimal system by enabling additional features individually. Doing with a minimal configuration is also helpful in debugging. If the error is not available in the minimal system, features are added individually and the search for the error goes on.
Here is the minimal configuration needed to run nginx:
# /etc/nginx/nginx.conf
events {} # event context have to be defined to consider config valid
http {
server {
listen 80;
server_name javatpoint.co www.javatpoint.co *.javatpoint.co;
return 200 "Hello";
}
}
Root, location and try_files directives
root directive
The root directive is used to set the root directory for requests, allowing nginx to map the incoming request onto the file system.
server {
listen 80;
server_name javatpoint.co;
root /var/www/javatpoint.co;
}
It allows nginx to return server content according to the request:
javatpoint.co:80/index.html # returns /var/www/javatpoint.com/index.html
javatpoint.co:80/foo/index.html # returns /var/www/javatpoint.com/foo/index.html
Location Directive
The location directive is used to set the configuration depending on the requested URI (Uniform Resource Identifier).
The syntax is:
location [modifier] path
Example:
location /foo {
# ...
}
When no modifier is given, the path is treated as a prefix, after which anything can follow. The above example will match:
/foo
/fooo
/foo123
/foo/bar/index.html
...
We can also use multiple location directives in a given context:
server {
listen 80;
server_name javatpoint.co;
root /var/www/javatpoint.co;
location / {
return 200 "root";
}
location /foo {
return 200 "foo";
}
}
javatpoint.co:80 / # => "root"
javatpoint.co:80 /foo # => "foo"
javatpoint.co:80 /foo123 # => "foo"
javatpoint.co:80 /bar # => "root"
Nginx also provides a few modifiers which can be used in conjunction with the location directive.
Modifier has assigned precedence:
= - Exact match
^~ - Preferential match
~ && ~* - Regex match
no modifier - Prefix match
First of all, nginx will check for any exact matches. If it does not exist, it will look for preferential ones. If this match also fails, regex matches will be tested in the order of their appearance. If everything else fails, the last prefix match will be used.
location /match {
return 200 'Prefix match: will match everything that starting with /match';
}
location ~* /match[0-9] {
return 200 'Case insensitive regex match';
}
location ~ /MATCH[0-9] {
return 200 'Case sensitive regex match';
}
location ^~ /match0 {
return 200 'Preferential match';
}
location = /match {
return 200 'Exact match';
}
/match # => 'Exact match'
/match0 # => 'Preferential match'
/match1 # => 'Case insensitive regex match'
/MATCH1 # => 'Case sensitive regex match'
/match-abc # => 'Prefix match: matches everything that starting with /match'
try_files directive
This directive tries different paths and will return whichever is found.
try_files $uri index.html =404;
So /foo.html will try to return files in the following order:
$uri (/foo.html);
index.html
If none is found:404
If we define try_files in a server context, and then define a location that finds all requests, our try_files will not be executed. This happens because try_files in the server context defines its pseudo-location, which is the least specific location possible. Hence, defining location / will be more specific than our pseudo-location.
server {
try_files $uri /index.html =404;
location / {
}
}
Thus, we should avoid try_files in a server context:
server {
location / {
try_files $uri /index.html =404;
}
}