nginx gzip_static: why are the non-compressed files required?

Solution 1:

It's possible that you've found a bug. But in general you want both files anyway, for three reasons:

  1. A few clients won't request compressed data, and if you force it on them with gzip_static always; they might not understand it.
  2. To ensure that the file is always found, and the request isn't passed upstream to Rails or being caught by the 404 handler (the possible bug). One of which is probably what's happening.
  3. Having nginx compress or uncompress the file at runtime means it must do so repeatedly, eating up valuable CPU that could be used to run your application. It's much less CPU intensive to simply send a static resource.

Solution 2:

Uncompressed files are not required on Nginx 1.6 with:

    location ~ \.txt$ {
        gzip_static on;
        gunzip on;
    }

Both curl http://localhost/index.txt and curl -H "Accept-Encoding: gzip" http://localhost/index.txt | gunzip now work fine with just /srv/www/localhost/index.txt.gz in my root directory.

Solution 3:

Contrary to what @hendry says, I need to keep original files.

I use nginx 1.15.9 (Ubuntu).

gzip_static is compiled in:

nginx -V 2>&1 | grep "\-\-with\-http_gzip_static_module

gunzip is compiled in:

nginx -V 2>&1 | grep "\-\-with\-http_gunzip_module".

I have found this, though it may be outdated:

try_files is not aware of gzip_static; but nginx will still honour it if both the non-gz and .gz files exist. This differs from the "normal" gzip_static handling which will serve the .gz version if appropriate, whether or not non-gz exists. - http://mailman.nginx.org/pipermail/nginx/2012-June/034102.html

It seems that try_files requires the original file to work there and is not affected by gzip_static always. That's because try_files $uri =404 requires the $uri file to exist. - https://trac.nginx.org/nginx/ticket/1570

This is my nginx.conf:

events {
    worker_connections 768;
}

http {
    server {
        # Enable static gzip
        gzip_static on;
        gunzip on;

        listen 8080 default_server;
        listen [::]:8080 default_server;

        root /home/user/projects/project1/build;

        location / {
            try_files $uri /index.html;
        }
    }
}

Run it with sudo nginx -t -c nginx.conf -p $PWD.

Restart with sudo killall -9 nginx; sudo nginx -c nginx.conf -p $PWD; ps aux | grep nginx.