Do you have a running instance of NGINX and wanted to add Brotli compression? What if you don’t want to recompile a custom web server from source or replace your auto-updating repo-installed version? You can create dynamic Brotli modules which upgrade whenever NGINX does.
The bash script below explains the installation steps. Feel free to study and execute the codes step-by-step. That may help you troubleshoot any peculiarities in your system. Otherwise, simply run the script.
You may choose to automate the installation by simply running the script above. In its default settings, it will process the version number you will pass to it. To get your NGINX’s version number run this command:
nginx -v
nginx version: nginx/1.17.1
Since the version number in this example is 1.17.1, after you have downloaded the bash script above, go to the directory where the script is and run these commands:
chmod +x mkbrotli
./mkbrotli 1.17.1
You may now chill and relax as the script automagically downloads, builds, and installs the dynamic modules for you. If the script runs through errors please let me know in the comments below so I may make adjustments to it.
Activating the modules
Now that we have the modules, there are two configuration steps needed to activate Brotli compression. First, load the modules in NGINX’s main configuration file (mine was at /etc/nginx/nginx.conf
). You can get your config file path by running this command:
nginx -V 2>&1 | grep -o 'conf-path=[^ ]*' | sed 's/conf-path=//'
Now edit NGINX’s conf file. Outside any block { ... }
, maybe on the top section of the file, add these lines:
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
# http {
# ...
# }
Second, activate Brotli (and set its configuration directives, aka settings) either inside the http
block of NGINX’s conf file, or the server
block of your domain configs (e.g. files in nginx/sites-enabled/
). As for me, I placed these directives in the nginx/snippets/
folder and called them via include
in my domain configs.
Auto-update with NGINX
One potential problem with dynamic modules is when NGINX automatically upgrades via a package manager (e.g. apt
, yum
, or pacman
). If you’re like me, all upgrades in my server are automated by scripts. You see, dynamic modules are version-specific. NGINX is set not to load modules that were built for a different version. So how will Brotli modules automatically upgrade together with NGINX?
The answer is to hook on the package manager during upgrades. In apt
this may be a two- or three-step process:
- Hook to
apt
and call a worker script. (Alternatively, the hook could directly callmkbrotli
and thus skip the need for a worker script.) - The worker script calls one or more build scripts to update the dynamic modules.
- Build scripts will build and install the new modules right before NGINX upgrades.
Here is my hook file in /etc/apt/apt.conf.d/
:
The worker script I use:
And finally the build script for this one is… (drum roll please)… of course mkbrotli
. 😉 I hope that Brotli could be natively supported by NGINX in the future. It’s awesome. For now, we have this workaround. Enjoy the compression!
Google PageSpeed
Another project that aims to speed things up on the web is Google’s best-practices optimization called PageSpeed. I also made a Bash script to automate installation of PageSpeed on a running NGINX server. If you’re interested, check out this post: Adding PageSpeed to an Already-running NGINX Instance.
83 Comments
Nigel · July 27, 2019 at 11:18 pm
I get this error on nginx test
module “/usr/share/nginx/modules/ngx_http_brotli_filter_module.so” is not binary compatible in /etc/nginx/nginx.conf
Any ideas?
Majal Mirasol · July 28, 2019 at 5:49 pm
Hi Nigel! We should supply to the script the same version of NGINX we are running. Have you checked via
nginx -v
? The warning will also show the version number the module was built for, and your running NGINX’s version number. Can you please post the full warning message here along with the mismatched version numbers?Lowi · August 8, 2019 at 10:13 pm
Hi, thanks for the script. I get the same error and I’m sure I installed the correct version
…
Sucessfully built Brotli for NGINX 1.14.0 in /usr/lib/nginx/modules
####################################################################
$ nginx -t
nginx: [emerg] module “/usr/share/nginx/modules/ngx_http_brotli_filter_module.so” is not binary compatible in /etc/nginx/nginx.conf test failed
$ nginx -v
nginx version: nginx/1.14.0 (Ubuntu)
Majal Mirasol · August 8, 2019 at 10:21 pm
That’s interesting… I’m pretty sure it works in my system. In fact it is running on this very website’s server. Hmmm… I’ll try to look more into this. Can you please supply more relevant details of your system? It may help us pinpoint and troubleshoot this issue. Thanks for the help!
Looking again, I’d just like to confirm also that your test command should be:
$ sudo nginx -t
rather than$ nginx -t
?Just guessing. Or the problem may be deeper than this… Thank you for your inputs! 🙂
Scott · August 31, 2019 at 3:00 pm
I got the same issue. It’s because you need to configure the module with the same options as nginx -V in the system (which is a lot when using debian bionic for example) – once I updated the script to contain the extra config options it worked
Majal Mirasol · August 31, 2019 at 3:42 pm
Hi Scott! Nice find. The configure step flag
--with-compat
is supposedly designed to handle that. But I think I read somewhere that it may not also work with certain configurations of NGINX. Thanks for pinning this. I’ll soon update the script which will include flags fromnginx -V
. Is it also okay if you could post how yourconfigure
command looked like? I and the readers here really appreciate all the help! 🙂Majal Mirasol · September 3, 2019 at 12:00 am
Hello Scott! I’ve just updated the script. Please find new section
confparams
in it. 🙂 Thanks for your help!Majal Mirasol · September 2, 2019 at 11:55 pm
Hi Lowi! A comment by Scott identified the culprit: your NGINX was likely configured without the
--with-compat
flag. I’ve updated the script where you can now choose to load the configure parameters of the installed NGINX in your system. Please see section onconfparams
and uncomment one of the commands that will work for you. Have a good day!Remco · September 12, 2019 at 8:55 pm
Hi Majal, i keep getting the binary not compatible error, even with uncommenting one of the 3 confparams you provided in the script.
nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.1 11 Sep 2018 (running with OpenSSL 1.1.1c 28 May 2019)
TLS SNI support enabled
configure arguments: –with-cc-opt=’-g -O2 -fdebug-prefix-map=/build/nginx-DUghaW/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2′ –with-ld-opt=’-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC’ –prefix=/usr/share/nginx –conf-path=/etc/nginx/nginx.conf –http-log-path=/var/log/nginx/access.log –error-log-path=/var/log/nginx/error.log –lock-path=/var/lock/nginx.lock –pid-path=/run/nginx.pid –modules-path=/usr/lib/nginx/modules –http-client-body-temp-path=/var/lib/nginx/body –http-fastcgi-temp-path=/var/lib/nginx/fastcgi –http-proxy-temp-path=/var/lib/nginx/proxy –http-scgi-temp-path=/var/lib/nginx/scgi –http-uwsgi-temp-path=/var/lib/nginx/uwsgi –with-debug –with-pcre-jit –with-http_ssl_module –with-http_stub_status_module –with-http_realip_module –with-http_auth_request_module –with-http_v2_module –with-http_dav_module –with-http_slice_module –with-threads –with-http_addition_module –with-http_geoip_module=dynamic –with-http_gunzip_module –with-http_gzip_static_module –with-http_image_filter_module=dynamic –with-http_sub_module –with-http_xslt_module=dynamic –with-stream=dynamic –with-stream_ssl_module –with-mail=dynamic –with-mail_ssl_module
You got any idea what i can do?
104990#104990: module “/usr/lib/nginx/modules/ngx_http_brotli_static_module.so” is not binary compatible in /etc/nginx/nginx.conf
Majal Mirasol · September 15, 2019 at 8:38 pm
Hi Remco! It appears that the source of this issue is because NGINX could be just be configured in so many different ways. My NGINX comes vanilla from Ubuntu’s repos and works out of the box without even using the
confparams
part of the script. It seems that you have a customized build of NGINX. You may likely troubleshoot your issue by playing with the values ofconfparams
. How about feedingconfparams
directly with your configuration parameters starting from--prefix=
up to the end of the line? What I also usually do with bash scripts is to run the commands step-by-step in a terminal and manually check for errors. I’m sorry but I cannot test your issue since we are using different configurations of NGINX. We will appreciate it if you could post back your findings about your specific setup. It will be helpful to other readers who may also be using custom NGINX builds. Enjoy your day!Igor «InoY» Z. · August 8, 2019 at 7:45 pm
Thank you! I do not try this manual yet but it is exactly what I’ve been looking for!
Also I have a question: can I translate this manual to Russian? Of course with mention to you and links to your blog?
Majal Mirasol · August 8, 2019 at 9:28 pm
You’re welcome to do so Igor. I haven’t completed the Terms of Use for the site yet, but I’m planning that while others aspects of the site remains in copyright, the codes be released under GNU General Public License v3.0 copyleft. I love open source, and I’m happy to give back small contributions to make our world a better place. 🙂
SeCrEt BoY™ · September 30, 2019 at 2:18 am
Hook to apt and call a worker script. (Alternatively, the hook could directly call mkbrotli and thus skip the need for a worker script.)
The worker script calls one or more build scripts to update the dynamic modules.
Build scripts will build and install the new modules right before NGINX upgrades.
I have copied 2 your files to /etc/apt/apt.conf.d/05nginxmodules and /usr/local/sbin/nginx-mod-preinstall
And what do I need to do next sir?
And finally the build script for this one is… (drum roll please)… of course mkbrotli. >>> how to build?
Thanks for help!
Majal Mirasol · September 30, 2019 at 6:03 am
Hi SeCrEt BoY! If you copied those two files in their proper directories, and if
mkbrotli
is placed in/usr/local/sbin/
then all you have to do is wait until NGINX upgrades and check if theapt
hook works. Of course you will need to confirm first if themkbrotli
script is working well with your system, that is, if it runs and installs without issues.On your other question if I understood correctly, did you mean how to run
mkbrotli
and make it build Brotli? After you copiedmkbrotli
to/usr/local/sbin/
and made sure it is executable, just type this in the terminal:$ /usr/local/sbin/mkbrotli
and see whether it will be successful or not.I hope this helps.
somuch · November 18, 2019 at 3:29 pm
Hi, I’m new to Ubuntu and Nginx. Already installed a few VPS on my own. Reading this tutorial I can understand how to install Brotli, but I only partially understand about updating/upgrading part.
On your last part of tutorial about upgrading Nginx, I can upgrade Nginx if I follow those 3 steps (Hook, Worker Script, and Build Script). But on your build script, on last part, I shouldn’t restart Nginx when it’s hooked? I often restart Nginx because I change nginx conf sometimes, or restarting ubuntu when creating snapshot etc. Isn’t it fine to restart Nginx even if it’s hooked as long as it’s not upgraded?
Another question about hooking, I just need to put those 3 scripts? No need to send command through ssh?
Thanks!
Majal Mirasol · November 18, 2019 at 3:43 pm
Hi somuch! Thanks for dropping by.
Question 1 on restart: There is no need for the build script to restart NGINX if it is part of the hook since
apt
will automatically restart NGINX after a successful upgrade. What theapt
hook does is when a new version of NGINX is ready to be installed (upgraded) it calls the Brotli build script. Once the script finishes, it proceeds in upgrading NGINX. After which,apt
will cause the new version of NGINX to be started which should match the Brotli module version that the build script just made.Question 2 on
apt
hooks andssh
: I think you mean that in sending commands throughssh
, you refer to interactive commands you send directly to the server. If yes, then the hooks are non-interactive commands that sit as files in your server until a trigger starts them. In this case, a trigger is started whenapt
realizes that NGINX is bound to be upgraded. You don’t have to be there in anssh
connection for this to happen. The server should automatically perform this without user interaction.somuch · November 18, 2019 at 5:22 pm
For question 1
I see, it’s getting clearer now. So what you mean on build script line #73
# Start/restart NGINX.
specifically only when upgrading? So I can still usesystemctl reload nginx
as I always do as long as it’s not on upgrading process?For question 2, yes, the interactive command.Ok, so I just need to put the files in place.
Anyway, what will happen when Nginx not loading this Brotli module after upgrade (in case I missed something)? Will it serve gzip? Serving empty files? Or not serving file at all? Because on the config, Brotli configuration still on.
Thanks for the quick reply!
Majal Mirasol · November 18, 2019 at 9:55 pm
Question 1:
Yes, you may do that. Or you can just edit the script and uncomment the line on restarting NGINX. I tried to make this script as understandable as possible so others can play around and improve on it.
Question 2:
If the script fails to build, then there will be a mismatch on the module version and NGINX version. This will prevent NGINX from starting at all. So there will be no NGINX running.
I hope this clarifies your questions. 🙂
somuch · November 19, 2019 at 1:12 pm
Hi, I just tried to install Brotli, I followed the steps above EXCEPT for auto update with Nginx part. I got this error when trying to restart Nginx
nginx: [emerg] dlopen() "/usr/share/nginx/modules/ngx_http_brotli_filter_module.so" failed (/usr/share/nginx/modules/ngx_http_brotli_filter_module.so: cannot open shared object file: No such file or directory) in /etc/nginx/nginx.conf:6
Upon manually checking the module folder, the Brotli module isn’t there, both of them.
Then I checked the bash script run on SSH, I get this https://pastebin.com/S0wsDZy6
Several things not found, and at the end said
./configure: error: the HTTP gzip module requires the zlib library
although I already have zlib library (I tried to install itapt install zlib1g
and turns out I already have it).At the last lines it’s concluded that the install failed
make: *** No rule to make target 'modules'. Stop.
!! configure or make failed, exiting...
Any idea about this? Thanks!
Majal Mirasol · November 19, 2019 at 1:30 pm
Hi! Looks like you have a number of errors there. Would you like to try to run the commands one-by-one on a terminal and address each error message if any? We’ll be interested to know where the trouble lies and how it may be fixed.
somuch · November 19, 2019 at 2:04 pm
Ok, I’ll try, running the command on bash manually right? I’ll start it with `ngver=1.16.1′ as mine is that version.
Anyway, this is DigitalOcean VPS, Nginx built from DO repo.
Majal Mirasol · November 19, 2019 at 2:08 pm
Right. I’ve always wanted to check out DO, but never had the time. Please let us know what you’ll find out will work. Enjoy learning!
somuch · November 19, 2019 at 2:15 pm
I just ran it, put
ngver=1.16.1
but I didn’t change any${ngver}
because I think already supplied from the first statement, is this correct?When I ran this command
[ ${confparams} ] && nice -n 19 ionice -c 3 ./configure --add-dynamic-module=../ngx_brotli "${confparams}" || nice -n 19 ionice -c 3 ./configure --with-compat --add-dynamic-module=../ngx_brotli
A lot of things not found, and then exiting SSH when running this command
nice -n 19 ionice -c 3 make modules || { echo '!! configure or make failed, exiting...'; exit 4; }
When I redo all the steps, when I arrived at that last command, I removed the exit part, and I get this result:
make: *** No rule to make target 'modules'. Stop.
!! configure or make failed, exiting...
Majal Mirasol · November 19, 2019 at 2:23 pm
I think you should not move forward with succeeding commands when one of the commands fail. It looks like your configuration step has a number of missing dependencies. It will be good to address those as it will prevent the module from being properly built.
somuch · November 19, 2019 at 2:27 pm
Continuing, I fixed the problem! yay! GZIP module for HTTP not working despite I already installed ZLIB because I still don’t have its dependencies, so I do this
apt-get install libpcre3 libpcre3-dev zlib1g zlib1g-dev libssl-dev
as I found here https://askubuntu.com/questions/980145/cant-add-nginx-module-requires-zlib. Now the bash script run successfully, andnginx -t
is OK. Trying Brotli now.Majal Mirasol · November 19, 2019 at 2:30 pm
Congratulations! 🙂
somuch · November 19, 2019 at 5:07 pm
Brotli is working now, reducing 166KB web page (around 90KB is non media files) to 160KB. Don’t know about the actual speed improvement.
I’m using W3TC as caching plugin, it seems buggy on Brotli support. Despite smaller file size, it takes longer on waiting time before download, as if it always create Brotli on the fly while it actually already has Brotli files cached. Another thing is, for HTML files, it shows 2 accept encoding header, br and gzip, separated on 2 different header. On GTMetrix, it download the uncompressed file instead. Sigh…
Do you know any good caching/minify plugin?
Majal Mirasol · November 20, 2019 at 8:31 am
It tried a few plugins before, including W3TC, Varnish, Redis, Memcached, etc. But I eventually ended up using NGINX’s proxy_cache for local caching and Cloudflare’s CDN as the cloud cache. For me this takes away load from the server by not installing additional components into the system and keeping it as lean as possible.
hongliang · June 8, 2020 at 2:21 am
thank!!!!! it work for me
Maxim · December 5, 2019 at 5:56 am
Thanks, friend! It’s works! 🙂
But I had one error (while trying to execute the file):
“error: unable to execute ./mkbrotli: No such file or directory”
I found a solution here: https://unix.stackexchange.com/questions/144718/sudo-unable-to-execute-script-sh-no-such-file-or-directory
Majal Mirasol · December 5, 2019 at 11:21 am
Thanks! Oh really? Text encoding issue? 🙂 I just checked my file and so far so good. It’s made purely in Linux. So I’m not sure where the encoding change was introduced, whether in the CDN (not likely), or if the file passed through a Windows machine…? Anyways, I’m glad the script works for you.
Maxim · December 5, 2019 at 4:38 pm
Yeah, I copied “ctrl+c” to a file in windows. And then uploaded it to the server. I am newbie 🙂 This is of course my mistake.
Manuel · December 7, 2019 at 6:17 am
Hello,
Any idea what can i do?
Thanks.
sudo nginx -t
nginx: [emerg] module “/usr/share/nginx/modules/ngx_http_brotli_filter_module.so” version 1014001 instead of 1014000 in /etc/nginx/nginx.conf:4
nginx: configuration file /etc/nginx/nginx.conf test failed
manuel_ficko@vps1:~$ nginx -V
nginx version: nginx/1.14.0 (Ubuntu)
built with OpenSSL 1.1.1 11 Sep 2018
TLS SNI support enabled
configure arguments: –with-cc-opt=’-g -O2 -fdebug-prefix-map=/build/nginx-DUghaW/nginx-1.14.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2′ –with-ld-opt=’-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC’ –prefix=/usr/s
hare/nginx –conf-path=/etc/nginx/nginx.conf –http-log-path=/var/log/nginx/access.log –error-log-path=/var/log/nginx/error.log –lock-path=/var/lock/nginx.lock –pid-path=/run/nginx.pid –modules-path=/usr/lib/nginx/modules –http-client-body-temp-path=/var/lib/nginx/body –htt
p-fastcgi-temp-path=/var/lib/nginx/fastcgi –http-proxy-temp-path=/var/lib/nginx/proxy –http-scgi-temp-path=/var/lib/nginx/scgi –http-uwsgi-temp-path=/var/lib/nginx/uwsgi –with-debug –with-pcre-jit –with-http_ssl_module –with-http_stub_status_module –with-http_realip_modul
e –with-http_auth_request_module –with-http_v2_module –with-http_dav_module –with-http_slice_module –with-threads –with-http_addition_module –with-http_geoip_module=dynamic –with-http_gunzip_module –with-http_gzip_static_module –with-http_image_filter_module=dynamic –w
ith-http_sub_module –with-http_xslt_module=dynamic –with-stream=dynamic –with-stream_ssl_module –with-mail=dynamic –with-mail_ssl_module
John Doe · April 12, 2020 at 11:10 pm
Line 50
[ ${confparams} ] && nice...
should be[ "${confparams}" ] && nice...
to avoid a/usr/local/sbin/mkbrotli: line 50: [: too many arguments
error.Majal Mirasol · April 13, 2020 at 3:15 pm
Thanks John Doe. Nice find. I edited the code, as well as others similar to this one, so they’ll be safer against such errors. It’s been quite a while since the code was last updated, until this helpful nudge. Thank you!
Davide Prevosto · May 1, 2020 at 5:40 am
Hello,
I have tried to use it on NGINX 1.18.0 but I am getting nginx: [emerg] module “/usr/share/nginx/modules/ngx_http_brotli_filter_module.so” is not binary compatible in /etc/nginx/nginx.conf:4
I already tried every
confparams
option. Have you got any suggestion, please?Thank you
Majal Mirasol · May 1, 2020 at 8:15 am
Hi Davide! Sorry it didn’t work for you. Does your warning message include the mismatched version numbers? Would you mind showing us?
Davide Prevosto · May 1, 2020 at 8:08 pm
Hi Majal,
unfortunately there isn’t any other error message other then the “binary compatible” one. I already use your script in the past, without any error. I do not understand, maybe issue it is causing by a particular NGINX module.
This is the nginx -V output.
nginx version: nginx/1.18.0
built with OpenSSL 1.1.1g 21 Apr 2020
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-PfVGlv/nginx-1.18.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-PfVGlv/nginx-1.18.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-PfVGlv/nginx-1.18.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-PfVGlv/nginx-1.18.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-PfVGlv/nginx-1.18.0/debian/modules/http-upstream-fair --add-dynamic-module=/build/nginx-PfVGlv/nginx-1.18.0/debian/modules/http-subs-filter
Any idea, maybe?
Majal Mirasol · May 1, 2020 at 11:27 pm
Hi Davide! We recently updated the script, specifically now found on line 52. Were you able to test with the newer script? Did the script throw any error messages before it performed the build process?
Davide Prevosto · May 2, 2020 at 12:49 am
Hi Majal, thank you for your reply.
I already use your last version, also few minutes ago. I can’t see any error.
This is the sucessully message:
Sucessfully built and installed latest Brotli for NGINX 1.18.0
Modules can be found in /usr/lib/nginx/modules
Next step: Configure dynamic modules and reload/restart NGINX.
No errors were shown before the end of the script.
Thank you
Davide Prevosto · May 2, 2020 at 12:51 am
PS. Pay attention at your website cache system: for example new comments are not shown after a reply. I needed to add a query string to invalidate your page cache 😉
Majal Mirasol · May 2, 2020 at 3:51 pm
Thanks for the heads up. 🙂 Supposedly commenters should not receive a cached page. But looks like that’s not the case. I use Cloudflare workers. BTW, when I do CTRL + F5, it loads up the fresh page. I’ll look into it. Thanks!
Now on the script, I’ll see if I can spin up a 1.18.0. I’m still on 1.16.1. 🙂
Davide Prevosto · May 2, 2020 at 3:57 pm
I was finally able to upgrade our BROTLI modules, without your bash script. I did run manually. I don’t know yet which module causes the issue, maybe I did something wrong.
Majal Mirasol · May 2, 2020 at 4:24 pm
Happy to hear that. 🙂 So that means the modules properly installed? We’d appreciate feedback when you’ll be able to find out what went wrong. Thanks a lot!
Davide Prevosto · May 2, 2020 at 4:37 pm
Yes Majal, Brotli is fully working on our server, with NGINX 1.18.0
Unfortunately I wasn’t able to use your script (I always used it, since months). Thanks for sharing your knowledge, I envy you a lot 🙂
Sweet Katarina (@Kata_Du_Coudont) · May 21, 2020 at 12:58 pm
How did you do that?
Davide Prevosto · May 21, 2020 at 2:28 pm
Hello @Kata_Du_Coudont,
I have manually compiled the module, trying to remove the dynamic NGINX modules (nginx -V to list them)
Strike · May 9, 2020 at 6:37 am
You need to work on your SEO because this article was nearly impossible to find but the content here is GOLDEN. Too many articles assuming I want to bake my own nginx + brotli cake but I just wanted to adhoc brotli to my existing install. Thank you so much.
Majal Mirasol · May 9, 2020 at 6:55 am
Thanks for the compliment. When I realized this post is helpful, I reposted this article at dev.to and Medium with canonicals pointing back here. But well, it looks like not a lot found it so interesting I guess… Your tip is very much appreciated. 🙂 Have a fine day!
Lee Tea · May 10, 2020 at 1:03 pm
Thank you, this is very helpful!
Developer · May 17, 2020 at 9:09 pm
Tried everything, uncommenting setting confparams, running without params at all. It’s building but
sudo nginx -t
nginx: [emerg] module "/usr/lib/nginx/modules/ngx_http_brotli_filter_module.so" is not binary compatible in /etc/nginx/nginx.conf:1
nginx: configuration file /etc/nginx/nginx.conf test failed
I’m using ubuntu 18
Distributor ID: Ubuntu
Description: Ubuntu 18.04.2 LTS
Release: 18.04
Codename: bionic
YUSSUP BUGACHEEV · May 18, 2020 at 8:34 pm
I have installed it using this guide.
https://www.vultr.com/docs/add-brotli-support-to-nginx-on-ubuntu-18-04
Anyway, thanks for you work.
Majal Mirasol · May 18, 2020 at 9:23 pm
I’m glad that worked for you Yussup. And it’s good to see more articles being written for this topic. I wasn’t able to find one when I jumped on this a year ago. Thanks for sharing that link. Have a good day keep safe!
Sweet Katarina (@Kata_Du_Coudont) · May 21, 2020 at 3:30 pm
Hi Majal,
I just today installed brotli on nginx 1.18.0. I’ve spend about 3 hours till it worked. I’ve used your script few months ago for 1.16.1 version and it worked somehow, now it dont, giving me a “is not binary compatible” error. So i have a few notes:
1) custom moduledir should me after auto_detection, because it sometimes not correct. I’m using fedora 30, and nginx configured with
–modules-path=/usr/lib64/nginx/modules
but it’s loading modules only from /usr/share/nginx/modules. I dont know why. So autodetection doesn’t work.
2) The error in your script is in $confparam passing, somehow the quot appears in the configure arguments. It impossible to notice unless you do actual “make” command.
the GOOD system nginx show this:
nginx -V
nginx version: nginx/1.18.0
built by gcc 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
built with OpenSSL 1.1.1d FIPS 10 Sep 2019 (running with OpenSSL 1.1.1g FIPS 21 Apr 2020)
TLS SNI support enabled
configure arguments: –prefix=/usr/share/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib64/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/var/lib/nginx/tmp/client_body –http-proxy-temp-path=/var/lib/nginx/tmp/proxy –http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi –http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi –http-scgi-temp-path=/var/lib/nginx/tmp/scgi –pid-path=/run/nginx.pid –lock-path=/run/lock/subsys/nginx –user=nginx –group=nginx –with-file-aio –with-ipv6 –with-http_ssl_module –with-http_v2_module –with-http_realip_module –with-stream_ssl_preread_module –with-http_addition_module –with-http_xslt_module=dynamic –with-http_image_filter_module=dynamic –with-http_sub_module –with-http_dav_module –with-http_flv_module –with-http_mp4_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_random_index_module –with-http_secure_link_module –with-http_degradation_module –with-http_slice_module –with-http_stub_status_module –with-http_perl_module=dynamic –with-http_auth_request_module –with-mail=dynamic –with-mail_ssl_module –with-pcre –with-pcre-jit –with-stream=dynamic –with-stream_ssl_module –with-google_perftools_module –with-debug –with-cc-opt=’-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection’ –with-ld-opt=’-Wl,-z,relro -Wl,–as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E’
and compiled custom nginx binary show this:
./nginx -V
nginx version: nginx/1.18.0
built by gcc 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)
configure arguments: –add-dynamic-module=../ngx_brotli –prefix=’/usr/share/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib64/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/var/lib/nginx/tmp/client_body –http-proxy-temp-path=/var/lib/nginx/tmp/proxy –http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi –http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi –http-scgi-temp-path=/var/lib/nginx/tmp/scgi –pid-path=/run/nginx.pid –lock-path=/run/lock/subsys/nginx –user=nginx –group=nginx –with-file-aio –with-ipv6 –with-http_ssl_module –with-http_v2_module –with-http_realip_module –with-stream_ssl_preread_module –with-http_addition_module –with-http_xslt_module=dynamic –with-http_image_filter_module=dynamic –with-http_sub_module –with-http_dav_module –with-http_flv_module –with-http_mp4_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_random_index_module –with-http_secure_link_module –with-http_degradation_module –with-http_slice_module –with-http_stub_status_module –with-http_perl_module=dynamic –with-http_auth_request_module –with-mail=dynamic –with-mail_ssl_module –with-pcre –with-pcre-jit –with-stream=dynamic –with-stream_ssl_module –with-google_perftools_module –with-debug –with-cc-opt=’-O2 -g -pipe -Wall -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -Wp,-D_GLIBCXX_ASSERTIONS -fexceptions -fstack-protector-strong -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -specs=/usr/lib/rpm/redhat/redhat-annobin-cc1 -m64 -mtune=generic -fasynchronous-unwind-tables -fstack-clash-protection -fcf-protection’ –with-ld-opt=’-Wl,-z,relro -Wl,–as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E”
Notice that quote after –prefix begins, and end till the end of string. I dont know how to fix it, but the problem is there. When i configured all that string manually – the “make modules” gived me good .so files without errors.
Sweet Katarina (@Kata_Du_Coudont) · May 21, 2020 at 3:48 pm
Yep. I finally fixed it. You should change 54 line
[ “${confparams}” ] && nice -n 19 ionice -c 3 ./configure –add-dynamic-module=../ngx_brotli “${confparams}” || nice -n 19 ionice -c 3 ./configure –with-compat –add-dynamic-module=../ngx_brotli
to this
[ “${confparams}” ] && nice -n 19 ionice -c 3 “./configure –add-dynamic-module=../ngx_brotli ${confparams}” || nice -n 19 ionice -c 3 ./configure –with-compat –add-dynamic-module=../ngx_brotli
Majal Mirasol · May 21, 2020 at 4:25 pm
Hi Sweet Katarina! Awesome find! I just adjusted the code to implement your suggestion in line 53. I tested it and it works! Also, about your
--prefix
, I made another entry that hopefully will match your custom NGINX prefix. It is in line 24. Thank you for sharing your debugging here. 🙂Sweet Katarina (@Kata_Du_Coudont) · May 21, 2020 at 6:50 pm
thank you =)
solut2000 · May 28, 2020 at 2:23 pm
Looks awesome!! I’ll try it!
solut2000 · May 29, 2020 at 1:05 am
It works like charm!
But I need more packages.
apt install libperl-dev libpcre3 libpcre3-dev libssl-dev openssl libgeoip-dev zlib1g-dev libxslt1-dev git python2.7 python-dev brotli libtool autoconf automake
Majal Mirasol · May 29, 2020 at 5:16 am
Thank you for letting us know that it works solut2000. 🙂 As well as your package requirements. Have a good day and keep safe!
Daniel L · August 14, 2020 at 2:11 pm
Thanks for the script! It worked well for me on Debian 10.
One minor issue I have with it is that it defaults to the Nginx module directory (eg. /usr/lib/nginx/modules), however /usr/lib/ should only ever be used for libraries managed by the system’s package manager. Manually compiled things should always go into /usr/local/. Because of that, I feel like it’d be a good idea to default the script to /usr/local/lib/nginx/modules. What do you think?
Majal Mirasol · August 14, 2020 at 2:59 pm
Hi Daniel! Thank you for your good suggestion. I like being standardized as well. From the comments, it became clear to me that the majority of the errors when running this script is because there are so many different builds of NGINX. (Well, freedom of open source.) To minimize the errors, the script tries to automatically figure out the modules path from the build configurations of the currently installed NGINX. In this way, it can adapt to where your specific NGINX build will be looking for modules by default.
If you noticed the line
# moddir=/path/to/modules/directory
, there is the possibility of setting one’s own preferred modules directory manually.Thanks for stopping by. Life is indeed full of compromises. Stay safe!
Mufaddal B · August 14, 2020 at 7:40 pm
I have the binary not compatible issue coming even after many builds. Please find the link to check what steps are taken.
https://stackoverflow.com/questions/63388446/ngx-http-brotli-filter-module-so-is-not-binary-compatible-in-etc-nginx-nginx-c
Mufaddal B · August 19, 2020 at 10:39 pm
root@ip-–––:~# sh mkbrotli.sh
################################################################################
Building Brotli for NGINX 1.17.3
Temporary build directory: /tmp/tmp.T7g8kN8PWM
Modules directory: /usr/lib/nginx/modules
–2020-08-19 14:29:21– https://nginx.org/download/nginx-1.17.3.tar.gz
Resolving nginx.org (nginx.org)… 52.58.199.22, 3.125.197.172, 2a05:d014:edb:5702::6, …
Connecting to nginx.org (nginx.org)|52.58.199.22|:443… connected.
HTTP request sent, awaiting response… 200 OK
Length: 1034586 (1010K) [application/octet-stream]
Saving to: ‘nginx-1.17.3.tar.gz’
nginx-1.17.3.tar.gz 100%[=====================================================================>] 1010K 639KB/s in 1.6s
2020-08-19 14:29:24 (639 KB/s) – ‘nginx-1.17.3.tar.gz’ saved [1034586/1034586]
Cloning into ‘ngx_brotli’…
remote: Enumerating objects: 31, done.
remote: Counting objects: 100% (31/31), done.
remote: Compressing objects: 100% (29/29), done.
remote: Total 200 (delta 11), reused 8 (delta 2), pack-reused 169
Receiving objects: 100% (200/200), 81.91 KiB | 1.14 MiB/s, done.
Resolving deltas: 100% (86/86), done.
Submodule ‘deps/brotli’ (https://github.com/google/brotli.git) registered for path ‘deps/brotli’
Cloning into ‘/tmp/tmp.T7g8kN8PWM/ngx_brotli/deps/brotli’…
Submodule path ‘deps/brotli’: checked out ‘d6d98957ca8ccb1ef45922e978bb10efca0ea541′
ionice: failed to execute ./configure –add-dynamic-module=../ngx_brotli –prefix=/etc/nginx –sbin-path=/usr/sbin/nginx –modules-path=/usr/lib/nginx/modules –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/nginx.pid –lock-path=/var/run/nginx.lock –http-client-body-temp-path=/var/cache/nginx/client_temp –http-proxy-temp-path=/var/cache/nginx/proxy_temp –http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp –http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp –http-scgi-temp-path=/var/cache/nginx/scgi_temp –user=nginx –group=nginx –with-http_ssl_module –with-http_realip_module –with-http_addition_module –with-http_sub_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_random_index_module –with-http_secure_link_module –with-http_stub_status_module –with-http_auth_request_module –with-http_xslt_module=dynamic –with-http_image_filter_module=dynamic –with-http_geoip_module=dynamic –with-http_perl_module=dynamic –with-stream=dynamic –with-stream_ssl_module –with-stream_ssl_preread_module –with-stream_geoip_module=dynamic –with-mail=dynamic –with-mail_ssl_module –add-dynamic-module=debian/extra/njs/nginx –add-dynamic-module=debian/extra/ngx_pagespeed –add-dynamic-module=debian/extra/headers-more-nginx-module –add-dynamic-module=debian/extra/lua-nginx-module –add-dynamic-module=debian/extra/naxsi/naxsi_src/ –add-dynamic-module=debian/extra/nginx-length-hiding-filter-module –add-dynamic-module=debian/extra/Session-Binding-Proxy/nginx_session_binding_proxy_module –add-dynamic-module=debian/extra/ngx_devel_kit –add-dynamic-module=debian/extra/ngx_http_upstream_order –add-dynamic-module=debian/extra/rds-json-nginx-module –add-dynamic-module=debian/extra/testcookie-nginx-module –add-dynamic-module=debian/extra/ngx_brotli –add-dynamic-module=debian/extra/ngx_postgres –add-dynamic-module=debian/extra/nchan –add-dynamic-module=debian/extra/ngx_http_auth_pam_module –add-dynamic-module=debian/extra/echo-nginx-module –add-dynamic-module=debian/extra/nginx-upstream-fair –add-dynamic-module=debian/extra/ngx_cache_purge –add-dynamic-module=debian/extra/ngx-fancyindex –add-dynamic-module=debian/extra/nginx-upload-progress-module –add-dynamic-module=debian/extra/ngx_http_substitutions_filter_module –add-dynamic-module=debian/extra/graphite-nginx-module –add-dynamic-module=debian/extra/nginx-module-vts –add-dynamic-module=debian/extra/nginx-ct –add-dynamic-module=debian/extra/nginx-rtmp-module –add-dynamic-module=debian/extra/nginx-ts-module –add-dynamic-module=debian/extra/nginx-module-sts –add-dynamic-module=debian/extra/nginx-module-stream-sts –add-dynamic-module=debian/extra/ngx_http_geoip2_module –add-dynamic-module=debian/extra/ngx_http_proxy_connect_module –with-threads –with-http_slice_module –with-file-aio –with-http_v2_module –with-cc-opt=’-g -O2 -fdebug-prefix-map=/build/nginx-CdgtSs/nginx-1.17.3-2=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -DTCP_FASTOPEN=23′ –with-ld-opt=’-Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now’: No such file or directory
checking for OS
+ Linux 5.3.0-1030-aws x86_64
checking for C compiler … found
+ using GNU C compiler
+ gcc version: 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
I am getting this error “No such file or directory” its above “checking for OS” line.
Majal Mirasol · August 20, 2020 at 5:27 am
Hi Mufaddal! Thanks for not easily giving up. That’s right, there’s an error in your logs:
ionice: failed to execute
…No such file or directory
. What I sometimes do when things go wrong is to do the steps manually, line by line, to make sure there’s no error in each step of the way. Do you think you could do that troubleshooting? There are also comments here on how to resolve thebinary not compatible
error. Please try them, and see if one of those works for you. 🙂Mufaddal B · August 29, 2020 at 12:15 pm
After running commands one by one,
~/nginx-1.17.3# ./configure --add-dynamic-module=../ngx_brotli --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-http_auth_request_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_perl_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-stream_geoip_module=dynamic --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=debian/extra/njs/nginx --add-dynamic-module=debian/extra/ngx_pagespeed --add-dynamic-module=debian/extra/headers-more-nginx-module --add-dynamic-module=debian/extra/lua-nginx-module --add-dynamic-module=debian/extra/naxsi/naxsi_src/ --add-dynamic-module=debian/extra/nginx-length-hiding-filter-module --add-dynamic-module=debian/extra/Session-Binding-Proxy/nginx_session_binding_proxy_module --add-dynamic-module=debian/extra/ngx_devel_kit --add-dynamic-module=debian/extra/ngx_http_upstream_order --add-dynamic-module=debian/extra/rds-json-nginx-module --add-dynamic-module=debian/extra/testcookie-nginx-module --add-dynamic-module=debian/extra/ngx_postgres --add-dynamic-module=debian/extra/nchan --add-dynamic-module=debian/extra/ngx_http_auth_pam_module --add-dynamic-module=debian/extra/echo-nginx-module --add-dynamic-module=debian/extra/nginx-upstream-fair --add-dynamic-module=debian/extra/ngx_cache_purge --add-dynamic-module=debian/extra/ngx-fancyindex --add-dynamic-module=debian/extra/nginx-upload-progress-module --add-dynamic-module=debian/extra/ngx_http_substitutions_filter_module --add-dynamic-module=debian/extra/graphite-nginx-module --add-dynamic-module=debian/extra/nginx-module-vts --add-dynamic-module=debian/extra/nginx-ct --add-dynamic-module=debian/extra/nginx-rtmp-module --add-dynamic-module=debian/extra/nginx-ts-module --add-dynamic-module=debian/extra/nginx-module-sts --add-dynamic-module=debian/extra/nginx-module-stream-sts --add-dynamic-module=debian/extra/ngx_http_geoip2_module --add-dynamic-module=debian/extra/ngx_http_proxy_connect_module --with-threads --with-http_slice_module --with-file-aio --with-http_v2_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-CdgtSs/nginx-1.17.3-2=. -specs=/usr/share/dpkg/no-pie-compile.specs -fstack-protector-strong -Wformat -Werror=format-security -DTCP_FASTOPEN=23' --with-ld-opt='-Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now'
checking for OS
+ Linux 5.3.0-1030-aws x86_64
checking for C compiler ... found
+ using GNU C compiler
+ gcc version: 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)
checking for gcc -pipe switch ... found
checking for --with-ld-opt="-Wl,-Bsymbolic-functions -specs=/usr/share/dpkg/no-pie-link.specs -Wl,-z,relro -Wl,-z,now" ... found
checking for -Wl,-E switch ... found
checking for gcc builtin atomic operations ... found
checking for C99 variadic macros ... found
checking for gcc variadic macros ... found
checking for gcc builtin 64 bit byteswap ... found
checking for unistd.h ... found
checking for inttypes.h ... found
checking for limits.h ... found
checking for sys/filio.h ... not found
checking for sys/param.h ... found
checking for sys/mount.h ... found
checking for sys/statvfs.h ... found
checking for crypt.h ... found
checking for Linux specific features
checking for epoll ... found
checking for EPOLLRDHUP ... found
checking for EPOLLEXCLUSIVE ... found
checking for O_PATH ... found
checking for sendfile() ... found
checking for sendfile64() ... found
checking for sys/prctl.h ... found
checking for prctl(PR_SET_DUMPABLE) ... found
checking for prctl(PR_SET_KEEPCAPS) ... found
checking for capabilities ... found
checking for crypt_r() ... found
checking for sys/vfs.h ... found
checking for poll() ... found
checking for /dev/poll ... not found
checking for kqueue ... not found
checking for crypt() ... not found
checking for crypt() in libcrypt ... found
checking for F_READAHEAD ... not found
checking for posix_fadvise() ... found
checking for O_DIRECT ... found
checking for F_NOCACHE ... not found
checking for directio() ... not found
checking for statfs() ... found
checking for statvfs() ... found
checking for dlopen() ... not found
checking for dlopen() in libdl ... found
checking for sched_yield() ... found
checking for sched_setaffinity() ... found
checking for SO_SETFIB ... not found
checking for SO_REUSEPORT ... found
checking for SO_ACCEPTFILTER ... not found
checking for SO_BINDANY ... not found
checking for IP_TRANSPARENT ... found
checking for IP_BINDANY ... not found
checking for IP_BIND_ADDRESS_NO_PORT ... found
checking for IP_RECVDSTADDR ... not found
checking for IP_SENDSRCADDR ... not found
checking for IP_PKTINFO ... found
checking for IPV6_RECVPKTINFO ... found
checking for TCP_DEFER_ACCEPT ... found
checking for TCP_KEEPIDLE ... found
checking for TCP_FASTOPEN ... found
checking for TCP_INFO ... found
checking for accept4() ... found
checking for kqueue AIO support ... not found
checking for Linux AIO support ... found
checking for int size ... 4 bytes
checking for long size ... 8 bytes
checking for long long size ... 8 bytes
checking for void * size ... 8 bytes
checking for uint32_t ... found
checking for uint64_t ... found
checking for sig_atomic_t ... found
checking for sig_atomic_t size ... 4 bytes
checking for socklen_t ... found
checking for in_addr_t ... found
checking for in_port_t ... found
checking for rlim_t ... found
checking for uintptr_t ... uintptr_t found
checking for system byte ordering ... little endian
checking for size_t size ... 8 bytes
checking for off_t size ... 8 bytes
checking for time_t size ... 8 bytes
checking for AF_INET6 ... found
checking for setproctitle() ... not found
checking for pread() ... found
checking for pwrite() ... found
checking for pwritev() ... found
checking for sys_nerr ... found
checking for localtime_r() ... found
checking for clock_gettime(CLOCK_MONOTONIC) ... found
checking for posix_memalign() ... found
checking for memalign() ... found
checking for mmap(MAP_ANON|MAP_SHARED) ... found
checking for mmap("/dev/zero", MAP_SHARED) ... found
checking for System V shared memory ... found
checking for POSIX semaphores ... not found
checking for POSIX semaphores in libpthread ... found
checking for struct msghdr.msg_control ... found
checking for ioctl(FIONBIO) ... found
checking for struct tm.tm_gmtoff ... found
checking for struct dirent.d_namlen ... not found
checking for struct dirent.d_type ... found
checking for sysconf(_SC_NPROCESSORS_ONLN) ... found
checking for sysconf(_SC_LEVEL1_DCACHE_LINESIZE) ... found
checking for openat(), fstatat() ... found
checking for getaddrinfo() ... found
configuring additional dynamic modules
adding module in ../ngx_brotli
+ ngx_brotli was configured
adding module in debian/extra/njs/nginx
./configure: error: no debian/extra/njs/nginx/config was found
I receive this above error. Can you please help.
Majal Mirasol · August 29, 2020 at 12:36 pm
Hi Mufaddal! Would this help? https://serverfault.com/questions/904124/configure-error-no-nginx-auth-ldap-config-was-found
Mufaddal B · August 29, 2020 at 2:53 pm
Checked above link but that is not the issue as the error shows full path.
I tried removing that module from confparams and then ran the cmd again, now its showing
error: no Debian/extra/ngx_pagespeed/config was found
I dont know whether removing these modules from confparams will resolve the issue or installing these modules one by one and trying to install Brotli. Cant seem to figure a way out.
Mufaddal B · September 24, 2020 at 4:24 pm
Finally I got it working.
These are the steps I followed
nginx -v
apt-add-repository -y ppa:hda-me/nginx-stable
apt-get install brotli nginx-module-brotli
nano /etc/nginx/nginx.conf
nginx.conf
#include /etc/nginx/modules-enabled/*.conf;
user www-data;
worker_processes auto;
pid /run/nginx.pid;
load_module modules/ngx_http_brotli_filter_module.so;
load_module modules/ngx_http_brotli_static_module.so;
inside of http block
gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
brotli on;
brotli_comp_level 4;
brotli_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
brotli_static on;
Save the file.
nginx -t
service nginx restart
Done.
Jivan Pal · October 27, 2020 at 5:34 am
Thanks for the push in the right direction that this post gave me! After much fiddling with which config parameters to provide, and no luck with the help of your script (from which I just picked out the relevant commands rather than running directly), I ended up just looking at the source for the
ngx_brotli
module, and there is, helpfully, a README which says:So I had a look at all of the config parameters that
nginx -V
showed on my setup: Nginx 1.18.0 on Ubuntu 20.04, installed via thenginx-extras
package. The parameters show that, on whatever machine that package was built, the build directory is/build/nginx-5JShor/nginx-1.18.0
, and there are additional modules in/build/nginx-5JShor/nginx-1.18.0/debian
. You can get the latter files from [1], which is listed on [2] as one of the sources fornginx-extras
.I replicated the build setup for the Ubuntu package and was then able to build the Brotli module successfully. However, replicating the entire setup and then running
make modules
results in a lot of extra modules being compiled that we don’t need, because we already have them; they came withnginx-extras
. As such, we can remove all of the--add-dynamic-modules
parameters that appear innginx -V
, and we should keep all the rest. Doing this greatly reduces compilation time.We can also compile in one of our own directories such as
~/build
(rather than somewhere such as/build
which only root can access) by changing the debug parameter-fdebug-prefix-map
that is passed to GCC as appropriate.Overall, what I did is given in the script [3]. Hopefully this helps someone in a similar situation. Thanks again for this post!
[1] — Debian sources — http://archive.ubuntu.com/ubuntu/pool/main/n/nginx/nginx_1.18.0-0ubuntu1.debian.tar.xz
[2] — Info for package
nginx-extras
in Ubuntu repofocal-updates
— https://packages.ubuntu.com/focal-updates/nginx-extras[3] — Bash script to do everything for you — https://gist.github.com/jivanpal/ce90c0d34ead57bc33d10099278ab423
Majal Mirasol · October 27, 2020 at 6:03 am
Awesome work Jivan! 🙂 Thanks so much for sharing what you dug up and on how to do it. This is very helpful.
Nilas Gram · February 1, 2021 at 9:57 pm
Very helpful post, thanks a lot!
You’ve got a merge conflict in the script:
<<<<<<< HEAD
[ “${ngver}” ] || { echo “Please supply NGINX version. Exiting…”; exit 7; }
[ “${ngver}” ] || { echo; echo “Please set NGINX version. Exiting…”; echo; exit 7; }
Adam_W · March 1, 2021 at 11:56 pm
Hello,
everything is fine except apt upgrade gives:
/bin/sh: 1: /usr/local/sbin/nginx-mod-preinstall: Permission denied
E: Sub-process /usr/local/sbin/nginx-mod-preinstall returned an error code (126)
E: Failure running script /usr/local/sbin/nginx-mod-preinstall
Majal Mirasol · March 2, 2021 at 2:28 pm
Looks like you’re running it with
/bin/sh
. Could you please try to change it to/bin/bash
?Adam Wolak · March 3, 2021 at 4:00 am
I din’t run script. I just run apt update & apt upgrade
Majal Mirasol · March 3, 2021 at 3:34 pm
Do you need to use
sudo
? Or… should it be&&
instead of&
?Adam_W · March 3, 2021 at 5:02 pm
I am using root account (know- wrong) and making apt one by one
Hung Nguyen · March 26, 2021 at 5:06 pm
Hi Majal Mirasol! Thanks for your srcipt.
I’m using it on Centos and it works fine.
But I have a question, since I’m using Centos, where can I place the hook file to upgrade Brotli modules automatically upgrade together with NGINX?
Thanks so much.
Majal Mirasol · March 26, 2021 at 10:29 pm
Good to know that it works on CentOS Hung. I’m sorry I don’t have experience in CentOS which uses
yum
as package manager. This is different from Debian’sapt
. I hope Google will be able to help you findyum
‘s upgrade hooks. 🙂Prazzz · October 16, 2021 at 3:33 pm
Hi Majal, can I just re-run the script each time I upgrade nginx via apt?
Majal Mirasol · October 16, 2021 at 3:55 pm
Yes @Prazzz. You can run it right after the upgrade.
Ilia · April 11, 2022 at 11:30 pm
HI Majal, just wanted to say thank you for the script! It works great!
Majal Mirasol · April 11, 2022 at 11:32 pm
You’re welcome! Have a great day!