Basic Nginx snippets

I've recently migrated my hosting, finally severing all remaining ties with .NET after rewriting some remaining small experients and projects with Python. As I now have a full Linux instance to manage (at Amazon Lightsail, wanted to try it and looks I'm sticking with it), I've had to improve my Nginx skills from "barely make a site run under a Docker container" to "configure multiple static and dynamic sites running on different subdomains on the same machine". This post is a small recollection of things I needed to accomplish.

Error log default location:

/var/log/nginx/error.log

Subsites inside the same root server block (note that alias paths end with / while a server root path do not):

location /mysubpath/ {
        alias /my/path/to/mysubpath/;
        try_files $uri $uri/index.html =404;
}

Note: It is easier to follow the recommended rule of one /etc/nginx/sites-available/<name> entry per site or subsite instead of having a root path + location and then children location with different subpaths (using alias). I made it work even combining uWSGI and static sites but the config files were more complex, so I reverted to everything in its single file with a single server block.

Proxy uWSGI Python apps through Nginx using system sockets (and as a bonus, disabling default Nginx index file matching):

index wontmatch;

location / {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/mysocketname.sock;
}

Protect password and similar sensible files from being served:

location ~ /\. { deny  all; }

Making all path files have a default MIME type (CSV in the example):

location /mycsvs/ {
    types    { }
    default_type text/comma-separated-values;
}

Protecting with basic authentication (sample tutorial):

auth_basic "Password required";
auth_basic_user_file /mypathtopasswordfile/.htpasswd;

Subdomain aliases:

server_name myalias1.name.com myalias2.name.com name.com;

Custom headers:

# only for success http responses
add_header X-Custom-Header a_value;

# all http responses
add_header X-Custom-Header a_value always;

Redirections:

location /cv {
    return 302 $scheme://portfolio.kartones.net/curriculumvitae/;
}

Only allowing certain HTTP methods:

error_page 405 @error405;
location @error405 {
    add_header Allow "GET, HEAD" always;
}

if ( $request_method !~ ^(GET|HEAD)$ ) {
    return 405;
}

Optimizations

Fully removing Server header (not only Nginx version):

sudo apt-get update
sudo apt-get install nginx-extras

sudo vim /etc/nginx/nginx.conf

# inside `http {}` section add:
server_tokens off;
more_set_headers 'Server: ';

# Save, exit and:
sudo service nginx restart

GZip all statics (Javascript, CSS, etcetera), as by default only HTML and a few others get compressed:

sudo vim /etc/nginx/ngnix.conf

# Search for `gzip_types` and replace it by:
gzip_types text/plain text/css text/js text/xml text/javascript application/javascript application/x-javascript application/json application/xml application/rss+xml image/svg+xml;

Cache expiration rules for static content: Include or adapt expires.conf inside http, server or location config blocks:

location ~* \.(?:rss|atom)$ {
        expires 1h;
}
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|zip|svg|webm|htc)$ {
        expires 1M;
        access_log off;
        add_header Cache-Control "public";
}
location ~* \.(?:css|js)$ {
        expires 1M;
        access_log off;
}

Serving Static Content: Official article, has interesting parameters if you serve big static content files (pdfs, zips and the like).

Tags: Systems-IT

Basic Nginx snippets article, written by Kartones. Published on