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:
Now if take a look at the test-css.css
file, we can see it is not being compressed:
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