Creating a custom Nginx build for Ubuntu/Debian

I’ve been using the RTCamp Ubuntu package for Nginx because it had ngx_cache_purge and ngx_pagespeed modules builtin. The problem with is that it’s still stuck on Nginx 1.8 version which doesn’t support HTTP/2 so I had to figure out how to do my own build based on the latest Nginx mainline version.

These instructions apply to both Debian and Ubuntu even though for my example I use the Ubuntu 16.04 LTS. I’ll be adding ngx_cache_purge, ngx_pagespeed and headers-more modules in to the package.

Prepare for the build

I like to work on anything that require compiling in /usr/local/src so we’ll need to go there and you’ll need to get the nginx package signing key to make apt happy.

cd /usr/local/src
wget http://nginx.org/keys/nginx_signing.key
apt-key add nginx_signing.key

I’m using the mainline of Nginx which gets more frequent updates than stable but is still just as stable.

cat <<-EOF > /etc/apt/source.list.d/nginx.list
deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx
deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx
EOF

apt-get update

Get the build dependencies and the source code for nginx.

apt-get build-dep nginx
apt-get source nginx

At the time of writing this the latest version of nginx I get from the repository is 1.11.2. So the nginx source I get are in directory nginx-1.11.2. The debian package files are under debian in the source and that’s where I’m going to create modules directory for the code of the modules I want included.

mkdir nginx-1.11.2/debian/modules
cd nginx-1.11.2/debian/modules

Get the modules

Now in the modules directory I’m going to download and extract the code for each of the modules I want included.

wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz
tar -zxvf 2.3.tar.gz

That extracts the ngx_cache_purge module to directory ngx_cache_purge-2.3 remember that as we’ll need it later.

wget https://github.com/pagespeed/ngx_pagespeed/archive/v1.11.33.2-beta.tar.gz
tar -zxvf v1.11.33.2-beta.tar.gz
cd ngx_pagespeed-1.11.33.2-beta/
wget https://dl.google.com/dl/page-speed/psol/1.11.33.2.tar.gz
tar -zxvf 1.11.33.2.tar.gz

For Google Pagespeed you’ll need to get the nginx module and the pagespeed implementation. Again note the module directory ngx_pagespeed-1.11.33.2-beta.

wget https://github.com/openresty/headers-more-nginx-module/archive/v0.30.tar.gz
tar -zxvf v0.30.tar.gz

Again note the directory where headers more is extracted which in this case is headers-more-nginx-module-0.30.

Configure compiler arguments

The last thing to do before we can actually build this thing is we need to add the modules into the actual build. That happens by modifying the rules file under debian directory of nginx. I’ll simply add the –add-module lines as the last arguments to COMMON_CONFIGURE_ARGS. Note the backslash at the end of the line, make sure you remember to add it to the currently last argument which in my case is –with-ld-opt=”$(LDFLAGS)” so yours should look like this with the added lines bolded. 

COMMON_CONFIGURE_ARGS := 
 --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_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_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 
 --add-dynamic-module=debian/extra/njs-ef2b708510b1/nginx 
 --with-threads 
 --with-stream 
 --with-stream_ssl_module 
 --with-http_slice_module 
 --with-mail 
 --with-mail_ssl_module 
 --with-file-aio 
 --with-ipv6 
 $(WITH_HTTP2) 
 --with-cc-opt="$(CFLAGS)" 
 --with-ld-opt="$(LDFLAGS)" 
 --add-module="$(CURDIR)/debian/modules/ngx_cache_purge-2.3" 
 --add-module="$(CURDIR)/debian/modules/ngx_pagespeed-1.11.33.2-beta" 
 --add-module="$(CURDIR)/debian/modules/headers-more-nginx-module-0.30" 

Compile and build the package

Now you are ready to build the deb package. Make sure you are in the nginx source root.

cd /usr/local/src/nginx-1.11.2
dpkg-buildpackage -uc -b
cd ..

Install customized Nginx

Now you should have all the nginx packages built and can install them with dpkg but when you install them you need to remember to tell apt to hold the packages and not upgrade them from a newer release from the repository. If there is a new release that you want to upgrade to you need to repeat these steps.

dpkg --install nginx_1.11.2-1~xenial_amd64.deb
apt-mark hold nginx
dpkg --install nginx-module-geoip_1.11.2-1~xenial_amd64.deb
apt-mark hold nginx-module-geoip

Once you’ve installed the package you can verify that it indeed has the modules by running:

nginx -V 2>&1 | grep ngx_cache_purge -o

If you got back ngx_cache_purge then congrats it worked. If it didn’t then make sure your –add-module argument is correctly done.