Nginx – Tips & tricks

It’s time to add next and last episode for our Nginx blog series. This time post will not describe specific thing, but few different tips and tricks. You can use them to improve your site performance, add additional monitoring, or just serve some files only for special users. If you have any other ideas, feel free to comment and feedback – I can add your suggestions to this blog post, or create next episode. Fine, go to our configuration files.

Nginx installation and first configuration

Nginx virtual host configuration

Use PHP-FPM with Nginx

Describe and change php.ini settings

PHP-FPM – config improvements

Use strong Nginx encryption settings

Nginx optimizations, tips and tricks

Default virtual host

Our previous configuration only sets virtual hosts with specific names. What about any other domains which point to our server? They will be use first virtual host, and in the most cases, it isn’t good solution. We can handle all non-virtual hosts domains in default one:

 
server  
{
    server_name _;
    listen 80 default_server;
    server_name_in_redirect off;
 
    return 301 https://our-main-domain.com$request_uri;
}

Nginx stats page

Nginx has a special, internal page with webserver informations – about currently active connections, accepted requests, active headers reading/writing and waiting connections in keep-alive mode. It can be helpful in some cases. You can enable this data using stub_status directive on location context. Important thing is you should restrict access only to few IPs – VPN on server and using local connection is good option for that.

 
location /nginx_status 
{
    stub_status on;
    access_log   off;
    allow 127.0.0.1;
    deny all;
}

X-Accel access header

One of very interesting thing is X-Accel header. We can use it to handle restricted files – this header should be set by our backend (for example, by PHP) and then redirect user to restricted content. If there is X-Accel header with file path, it will work. If not, user will receive information about restricted access (standard 403 error page). There is an example with location context and alias:

 
location /restricted-files
{
    alias /restricted/files/;
    internal;
}

And also backend:

 
if ($userAllowed)
{
    header("X-Accel-Redirect: {$restrictedFilePath}");
    header('Content-type: application/octet-stream');
    header('Content-Disposition: attachment; filename="' . $fileName . '"');
    exit;
}

Error pages

Nginx has very simple, build-in error pages. You can use your error pages to make them more user-friendly. Solution is very simple – you must create directive for error pages and handle them in location:

 
error_page 403 404 = @error404;

location @error404 {
    try_files /error/404.html =404; 
}

Open files cache and expires headers

There is very simple way to significantly improve your websites loading time – cache static content like images, styles, javascript etc. on user browser. It this case, browser will request only real dynamic data, not these resources. You can also disable access logs for such files and use open file cache to improve handling:

 
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
    open_file_cache max=1000 inactive=120s;
    open_file_cache_valid 45s;
    open_file_cache_min_uses 2;
    open_file_cache_errors off;

    expires max;
    access_log off;
    log_not_found off;
    tcp_nodelay off;
}

Disable access and/or log for some files

If you do not want log access or errors for some files, or just deny access to data (like hidden files), just use this simple location examples:

 
location = /robots.txt  { access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }  
location ~ /\.          { access_log off; log_not_found off; deny all; }
location ~ ~$           { access_log off; log_not_found off; deny all; }

Cloudlare support

Do you know what is Clodflare? If yes, you know this service advantages. If not, I will describe this in next blog post, so stay tuned. I used to use Cloudflare if it is possible, it can also hide my server real IP, so… why not? The problem is that Cloudflare will not serve guests IPs directly to your server. Because it’s proxy, standard IP header will include Cloudflare IP, not real visitor. It’s simple to “fix”, you should add some code to all your virtual hosts (it’s a good idea to use it as separate file and just include):

 
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 104.16.0.0/12;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 131.0.72.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 2400:cb00::/32;
set_real_ip_from 2606:4700::/32;
set_real_ip_from 2803:f800::/32;
set_real_ip_from 2405:b500::/32;
set_real_ip_from 2405:8100::/32;
set_real_ip_from 2c0f:f248::/32;
set_real_ip_from 2a06:98c0::/29;

# use any of the following two
real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.