How to build nginx with Google PageSpeed module on Debian 8 (Jessie)
Authors: Falko Timme, F4RR3LL | Sven
This tutorials explains how to build nginx with the latest version of the nginx_pagespeed module on Debian Jessie. The PageSpeed module applies web performance best practices to pages, and associated assets (CSS, JavaScript, images) and therefore speeds up your web site and reduces load times.
1 Building nginx With PageSpeed
nginx does not support dynamic loading of modules, therefore we must rebuild it with PageSpeed support. We will build nginx as a .deb package so that we can replace our existing nginx installation with it (or easily install it on other systems).
Create the build directory first:
cd /usr/src
mkdir nginx-pagespeed && cd nginx-pagespeed
Make sure you have deb and deb-src lines for Jessie in /etc/apt/sources.list:
nano /etc/apt/sources.list
[...] deb http://ftp.de.debian.org/debian jessie main contrib non-free deb-src http://ftp.de.debian.org/debian jessie main contrib non-free [...]
Update your packages list and install some prerequisites:
apt-get update
apt-get install dpkg-dev build-essential zlib1g-dev libpcre3 libpcre3-dev unzip curl libcurl4-openssl-dev libossp-uuid-dev
Download the nginx sources and the build dependencies:
apt-get source nginx
apt-get build-dep nginx
Let's check our nginx version:
ls -l
[email protected]:/usr/src/nginx-pagespeed# ls -l
insgesamt 1388
drwxr-xr-x 10 root root 4096 Apr 29 22:16 nginx-1.6.2
-rw-r–r– 1 root root 604568 Dez 1 12:51 nginx_1.6.2-5.debian.tar.xz
-rw-r–r– 1 root root 2827 Dez 1 12:51 nginx_1.6.2-5.dsc
-rw-r–r– 1 root root 804164 Sep 17 2014 nginx_1.6.2.orig.tar.gz
Our nginx version is 1.6.2. Let's go to the debian/modules directory of the downloaded nginx sources...
cd /usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/
... and download the PageSpeed sources (you can check for the latest release on this page: https://github.com/pagespeed/ngx_pagespeed/releases - in this example the version is 1.9.32.3-beta; if your version differs, make sure to replace it in the rest of this tutorial):
wget https://github.com/pagespeed/ngx_pagespeed/archive/release-1.9.32.3-beta.zip
unzip release-1.9.32.3-beta.zip
mv ngx_pagespeed-release-1.9.32.3-beta/ ngx_pagespeed
cd ngx_pagespeed/
wget https://dl.google.com/dl/page-speed/psol/1.9.32.3.tar.gz
tar -xzvf 1.9.32.3.tar.gz
Let's edit the debian/rules file:
nano /usr/src/nginx-pagespeed/nginx-1.6.2/debian/rules
In that file you will find three configure_flags sections where the line:
–add-module=$(MODULESDIR)/ngx_pagespeed \
needs to be added:
in the section light_configure_flags after –without-http_uwsgi_module ,
in the section full_configure_flags after –with-mail_ssl_module,
in the section extras_configure_flags after –add-module=$(MODULESDIR)/nginx-development-kit
The resulting file should look like the one below (use the tab key to add the whitespace in front of the lines).
#!/usr/bin/make -f export DH_VERBOSE=1 debian_cflags:=$(shell dpkg-buildflags --get CFLAGS) $(shell dpkg-buildflags --get CPPFLAGS) debian_ldflags:=$(shell dpkg-buildflags --get LDFLAGS) # export necessary perl hardenging flags # see: src/http/modules/perl/Makefile.PL DEBIAN_NGINX_PERL_LDFLAGS:= $(debian_ldflags) export DEBIAN_NGINX_PERL_LDFLAGS FLAVOURS := full light extras MODULESDIR = $(CURDIR)/debian/modules BASEDIR = $(CURDIR) $(foreach flavour,$(FLAVOURS),$(eval BUILDDIR_$(flavour) = $(CURDIR)/debian/build-$(flavour))) DEB_BUILD_ARCH ?=$(shell dpkg-architecture -qDEB_BUILD_ARCH) ifeq ($(DEB_BUILD_ARCH),sparc) debian_cflags += -m32 -mcpu=ultrasparc endif ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) NUMJOBS = $(patsubst parallel=%,%,$(filter parallel=%,$(DEB_BUILD_OPTIONS))) MAKEFLAGS += -j$(NUMJOBS) endif # configure flags common_configure_flags := \ --with-cc-opt="$(debian_cflags)" \ --with-ld-opt="$(debian_ldflags)" \ --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 \ --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-ipv6 \ --with-http_ssl_module \ --with-http_stub_status_module \ --with-http_realip_module \ --with-http_auth_request_module light_configure_flags := \ $(common_configure_flags) \ --with-http_gzip_static_module \ --without-http_browser_module \ --without-http_geo_module \ --without-http_limit_req_module \ --without-http_limit_zone_module \ --without-http_memcached_module \ --without-http_referer_module \ --without-http_scgi_module \ --without-http_split_clients_module \ --without-http_ssi_module \ --without-http_userid_module \ --without-http_uwsgi_module \ --add-module=$(MODULESDIR)/ngx_pagespeed \ --add-module=$(MODULESDIR)/nginx-echo full_configure_flags := \ $(common_configure_flags) \ --with-http_addition_module \ --with-http_dav_module \ --with-http_geoip_module \ --with-http_gzip_static_module \ --with-http_image_filter_module \ --with-http_spdy_module \ --with-http_sub_module \ --with-http_xslt_module \ --with-mail \ --with-mail_ssl_module \ --add-module=$(MODULESDIR)/ngx_pagespeed \ --add-module=$(MODULESDIR)/nginx-auth-pam \ --add-module=$(MODULESDIR)/nginx-dav-ext-module \ --add-module=$(MODULESDIR)/nginx-echo \ --add-module=$(MODULESDIR)/nginx-upstream-fair \ --add-module=$(MODULESDIR)/ngx_http_substitutions_filter_module extras_configure_flags := \ $(common_configure_flags) \ --with-http_addition_module \ --with-http_dav_module \ --with-http_flv_module \ --with-http_geoip_module \ --with-http_gzip_static_module \ --with-http_image_filter_module \ --with-http_mp4_module \ --with-http_perl_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_spdy_module \ --with-http_sub_module \ --with-http_xslt_module \ --with-mail \ --with-mail_ssl_module \ --add-module=$(MODULESDIR)/headers-more-nginx-module \ --add-module=$(MODULESDIR)/nginx-auth-pam \ --add-module=$(MODULESDIR)/nginx-cache-purge \ --add-module=$(MODULESDIR)/nginx-dav-ext-module \ --add-module=$(MODULESDIR)/nginx-development-kit \ --add-module=$(MODULESDIR)/ngx_pagespeed \ --add-module=$(MODULESDIR)/ngx-fancyindex \ --add-module=$(MODULESDIR)/nginx-http-push \ --add-module=$(MODULESDIR)/nginx-lua \ --add-module=$(MODULESDIR)/nginx-upload-progress \ --add-module=$(MODULESDIR)/nginx-upstream-fair \ --add-module=$(MODULESDIR)/ngx_http_substitutions_filter_module %: dh [email protected] --with systemd override_dh_auto_configure: $(foreach flavour,$(FLAVOURS),config.arch.$(flavour)) override_dh_auto_build: $(foreach flavour,$(FLAVOURS),build.arch.$(flavour)) override_dh_strip: $(foreach flavour,$(FLAVOURS),strip.arch.$(flavour)) override_dh_clean: $(foreach flavour,$(FLAVOURS),clean.$(flavour)) dh_clean override_dh_installinit: dh_installinit --no-restart-on-upgrade --no-start --name=nginx override_dh_systemd_enable: dh_systemd_enable --name=nginx override_dh_installlogrotate: dh_installlogrotate --package nginx-common --name=nginx build.arch.%: $(MAKE) -C $(BUILDDIR_$*) build strip.arch.%: dh_strip --package=nginx-$(*) --dbg-package=nginx-$(*)-dbg config.arch.%: dh_testdir mkdir -p $(BUILDDIR_$*) cp -Pa $(CURDIR)/auto $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/conf $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/configure $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/contrib $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/src $(BUILDDIR_$*)/ cp -Pa $(CURDIR)/man $(BUILDDIR_$*)/ cd $(BUILDDIR_$*) && ./configure $($*_configure_flags) clean.%: rm -rf $(BUILDDIR_$*)
Then run:
cd /usr/src/nginx-pagespeed/nginx-1.6.2/ && dpkg-buildpackage -b
to build the new nginx .deb package. Afterwards, let's take a look at the generated packages:
cd /usr/src/nginx-pagespeed
ls -l
[email protected]:/usr/src/nginx-pagespeed# ls -l
insgesamt 99720
drwxr-xr-x 10 root root 4096 Apr 29 22:16 nginx-1.6.2
-rw-r–r– 1 root root 72086 Apr 29 23:06 nginx_1.6.2-5_all.deb
-rw-r–r– 1 root root 3961 Apr 29 23:08 nginx_1.6.2-5_amd64.changes
-rw-r–r– 1 root root 604568 Dez 1 12:51 nginx_1.6.2-5.debian.tar.xz
-rw-r–r– 1 root root 2827 Dez 1 12:51 nginx_1.6.2-5.dsc
-rw-r–r– 1 root root 804164 Sep 17 2014 nginx_1.6.2.orig.tar.gz
-rw-r–r– 1 root root 86540 Apr 29 23:06 nginx-common_1.6.2-5_all.deb
-rw-r–r– 1 root root 83716 Apr 29 23:06 nginx-doc_1.6.2-5_all.deb
-rw-r–r– 1 root root 3403690 Apr 29 23:08 nginx-extras_1.6.2-5_amd64.deb
-rw-r–r– 1 root root 31745456 Apr 29 23:08 nginx-extras-dbg_1.6.2-5_amd64.deb
-rw-r–r– 1 root root 3232788 Apr 29 23:07 nginx-full_1.6.2-5_amd64.deb
-rw-r–r– 1 root root 29932616 Apr 29 23:07 nginx-full-dbg_1.6.2-5_amd64.deb
-rw-r–r– 1 root root 3136400 Apr 29 23:07 nginx-light_1.6.2-5_amd64.deb
-rw-r–r– 1 root root 28975322 Apr 29 23:08 nginx-light-dbg_1.6.2-5_amd64.deb
We can now install nginx with PageSpeed support as follows:
dpkg --install nginx-common_1.6.2-5_all.deb nginx_1.6.2-5_all.deb nginx-full_1.6.2-5_amd64.deb
Then restart nginx:
service nginx restart
Let's check if the PageSpeed module was built successfully:
nginx -V
You should see the ngx_pagespeed module in the output:
[email protected]:/usr/src/nginx-pagespeed# nginx -V
nginx version: nginx/1.6.2
TLS SNI support enabled
configure arguments: –with-cc-opt='-g -O2 -fstack-protector-strong -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2' –with-ld-opt=-Wl,-z,relro –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 –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-ipv6 –with-http_ssl_module –with-http_stub_status_module –with-http_realip_module –with-http_auth_request_module –with-http_addition_module –with-http_dav_module –with-http_geoip_module –with-http_gzip_static_module –with-http_image_filter_module –with-http_spdy_module –with-http_sub_module –with-http_xslt_module –with-mail –with-mail_ssl_module –add-module=/usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/ngx_pagespeed –add-module=/usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/nginx-auth-pam –add-module=/usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/nginx-dav-ext-module –add-module=/usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/nginx-echo –add-module=/usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/nginx-upstream-fair –add-module=/usr/src/nginx-pagespeed/nginx-1.6.2/debian/modules/ngx_http_substitutions_filter_module
2 Configuring PageSpeed
To enable PageSpeed, open /etc/nginx/nginx.conf...
nano /etc/nginx/nginx.conf
... and add the lines pagespeed on; and pagespeed FileCachePath /var/ngx_pagespeed_cache; before any vhosts:
[...] pagespeed on; pagespeed FileCachePath /var/ngx_pagespeed_cache; ## # Virtual Host Configs ## include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*; [...]
Create the cache directory and reload nginx:
mkdir /var/ngx_pagespeed_cache
chown -R www-data:www-data /var/ngx_pagespeed_cache
service nginx reload
Let's load a page and check if PageSpeed is mentioned in the output:
curl -I -p http://localhost|grep X-Page-Speed
[email protected]:/usr/src/nginx-pagespeed# curl -I -p http://localhost|grep X-Page-Speed
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
X-Page-Speed: 1.9.32.3-4448
Now we can configure PageSpeed individually or each vhost, e.g. like this:
nano /etc/nginx/sites-available/example.com.vhost
server { [...] # let's speed up PageSpeed by storing it in the super duper fast memcached pagespeed MemcachedThreads 1; pagespeed MemcachedServers "localhost:11211"; # Filter settings pagespeed RewriteLevel CoreFilters; pagespeed EnableFilters collapse_whitespace,remove_comments; # Ensure requests for pagespeed optimized resources go to the pagespeed # handler and no extraneous headers get set. location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; } location ~ "^/ngx_pagespeed_static/" { } location ~ "^/ngx_pagespeed_beacon$" { } location /ngx_pagespeed_statistics { allow 127.0.0.1; deny all; } location /ngx_pagespeed_global_statistics { allow 127.0.0.1; deny all; } location /ngx_pagespeed_message { allow 127.0.0.1; deny all; } location /pagespeed_console { allow 127.0.0.1; deny all; } [...] }
The important line is the pagespeed EnableFilters line which tells PageSpeed which filters it should apply. You can find a list of all filters here: http://ngxpagespeed.com/ngx_pagespeed_example/
Don't forget to restart nginx afterwards:
service nginx reload
When you open a page now and take a look at the headers (e.g. with the Live HTTP headers add-on for FireFox), you should see an x-page-speed line. You can also check the HTML sources of your pages to see if the PageSpeed filters work as expected.
3 Links
- Google Developers' Blog: http://googledevelopers.blogspot.nl/2013/04/speed-up-your-sites-with-pagespeed-for.html
- ngx_pagespeed: https://developers.google.com/speed/pagespeed/ngx
- Building/using PageSpeed: https://github.com/pagespeed/ngx_pagespeed
- ngx_pagespeed Filter Examples: http://ngxpagespeed.com/ngx_pagespeed_example/