Nginx gzip compression not working despite following official Nginx documentation / online research

The Issue

I'm at wits end so decided to post a query, I am attempting to set up gzip compression on an nginx docker container after I noticed lighthouse was complaining a number of my clients sites don't have it enabled. All offending sites have gzip compression settings in their config with the right settings and types added but no matter what I change it comes through as uncompressed. I've tested this through both browser and using a CURL request and no change.

I've looked through numerous tickets both on here and elsewhere and none of the solutions have worked despite lots of config fiddling.

What I've tried

For the purposes of this ticket and testing I have created a completely 'virgin' docker project with a default.conf file containing the site config and a public/ folder containing an index.html and test-css.css file.

You can find this example project here: https://github.com/MajorFailz/so-issue-nginx-docker-example

The config file simply serves the folder and contains the gzip settings recommended by nginx's own article here: https://docs.nginx.com/nginx/admin-guide/web-server/compression/

Dockerfile

FROM nginx:1.21

RUN mkdir /app

WORKDIR /app

COPY ./public /app/public

COPY ./conf/default.conf /etc/nginx/conf.d/default.conf

default.conf

server {
    gzip on;
    gzip_types      text/plain application/xml text/css;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;

    location / {
        root /app/public;
    }
}

Testing with browser

When this project is booted up and viewed in chrome, opening the development tab and viewing the index.html shows that it is being served with gzip compression:

Example showing index.html in developer console

Now if take a look at the test-css.css file, we can see it is not being compressed:

Example showing test-css.css file without compression

Testing via console

So, after doing some research there appears to be instances were Chrome or various windows antiviruses and decompress things before reaching the browser. So I go and test from a linux VM using curl to attempt to fetch the file with gzip and see what it says.

master@apex:~$ curl -H "Accept-Encoding: gzip" -I http://www.apex.local/test-css.css
HTTP/1.1 200 OK
Server: nginx/1.18.0 (Ubuntu)
Date: Tue, 11 Jan 2022 15:38:00 GMT
Content-Type: text/css
Content-Length: 53790
Connection: keep-alive
Last-Modified: Tue, 11 Jan 2022 14:55:59 GMT
ETag: "61dd9a7f-d21e"
Accept-Ranges: bytes

So still no compression! So it doesn't appear to be the browser, additionally I used a site performance report website to test it and encountered the same issue.

From further research the issue can be if nginx doesn't have the gzip module installed so after digging I run this command from within the container which tests to see if it was compiled with gzip:

root@127b59858b48:/app# 2>&1 nginx -V | tr -- - '\n' | grep _module | grep gzip
http_gzip_static_module

So it has the module! So what the hey?

Additional information

I've tried numerous combinations of config settings and also tried different OS setups for the nginx docker image (my projects run on alpine so thought it may be a factor) but the results are consistent.

Client nginx config example

An example of the current configuration copy/pasted from one my clients websites:

    gzip on;
    gzip_min_length 10240;
    gzip_comp_level 1;
    gzip_vary on;
    gzip_disable msie6;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types
        # text/html is always compressed by HttpGzipModule
        text/css
        text/javascript
        text/xml
        text/plain
        text/x-component
        application/javascript
        application/x-javascript
        application/json
        application/xml
        application/rss+xml
        application/atom+xml
        font/truetype
        font/opentype
        application/vnd.ms-fontobject
        image/svg+xml;

Tickets for reference

I've looked at numerous tickets but these are three recent ones I've still got open in my browser:

  • https://serverfault.com/questions/915928/gzip-not-working-on-nginx/923396
  • nginx gzip compression doesn't seem to work
  • nginx gzip compression not working

It all works on my Debian 11 Host

$:/so-issue-nginx-docker-example# curl -Iv -H "Accept-Encoding: gzip" 127.1:49153/test-css.css
*   Trying 127.0.0.1:49153...
* Connected to 127.1 (127.0.0.1) port 49153 (#0)
> HEAD /test-css.css HTTP/1.1
> Host: 127.1:49153
> User-Agent: curl/7.74.0
> Accept: */*
> Accept-Encoding: gzip
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Server: nginx/1.21.5
Server: nginx/1.21.5
< Date: Wed, 12 Jan 2022 09:12:35 GMT
Date: Wed, 12 Jan 2022 09:12:35 GMT
< Content-Type: text/css
Content-Type: text/css
< Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: W/"61de99af-d21e"
ETag: W/"61de99af-d21e"
< Content-Encoding: gzip
Content-Encoding: gzip

I have noticed in your Browser as well as curl the NGINX Version is 1.18.0. The Dockerfile you have shared uses NGINX Version 1.21. Given that, are you sure you are sending the curl to the correct instance or is there any other NGINX server proxying the traffic before it reaches the "Dockerized" NGINX?

Can you please double check? I will test the setup with 1.18 to make sure it is not the version.

Update: It works with 1.18.0 as well

HTTP/1.1 200 OK
< Server: nginx/1.18.0
Server: nginx/1.18.0
< Date: Wed, 12 Jan 2022 09:52:00 GMT
Date: Wed, 12 Jan 2022 09:52:00 GMT
< Content-Type: text/css
Content-Type: text/css
< Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
Last-Modified: Wed, 12 Jan 2022 09:04:47 GMT
< Connection: keep-alive
Connection: keep-alive
< ETag: W/"61de99af-d21e"
ETag: W/"61de99af-d21e"
< Content-Encoding: gzip
Content-Encoding: gzip