Search form

Recompile Nginx (1.9+) Installed with Apt On Ubuntu 16.04

As mentioned in my older article on the subject, for many years Nginx had no hook for dynamically adding new modules, which meant having to recompile Nginx to add functionality. But the Nginx company has worked to address that issue: as of version 1.9.11, Nginx supports dynamic module loading.

Still, there may be cases where you want to recompile Nginx to permanently change its startup parameters or add/remove modules. This article presents two approaches to recompile Nginx 1.9+: one using the current version of Nginx installed from the Ubuntu 16.04 main repos, and one using the latest developmental ("mainline") version of Nginx from the Nginx PPA. As before, we're going to be compiling in the nginx-http-push-stream module as an example.

Method 1: Recompile Nginx from the Ubuntu.com Repos

Starting with a bare image of Ubuntu 16.04 Server, we install Nginx, gcc, and make:

root@ubuntu:/# apt-get install nginx build-essential

Let's check our Nginx version and compile flags. We're going to be using this almost as-is to recompile.

root@ubuntu:/# nginx -V
nginx version: nginx/1.10.0 (Ubuntu)
built with OpenSSL 1.0.2g-fips  1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security 
-Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' 
--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_gunzip_module 
--with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module 
--with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads

We'll be adding two new compilation flags:

--sbin-path=/usr/sbin/nginx
--add-module=/opt/nginx-push-stream-module

The first ensures that our Nginx binary lives in the same location as before, while the second ensures that our push-stream module is compiled in.

Get the latest source code for our Nginx version:

 
root@ubuntu:/# cd /opt
root@ubuntu:/opt/# wget http://nginx.org/download/nginx-1.10.1.tar.gz
root@ubuntu:/opt/# tar -xvzf nginx-1.10.1.tar.gz

Get the push-stream module:

 
root@ubuntu:/opt/# git clone http://github.com/wandenberg/nginx-push-stream-module.git

Install some prerequisites:

root@ubuntu:/# apt-get install libpcre3-dev libssl-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev

Stop Nginx:

root@ubuntu:/# /etc/init.d/nginx stop

Start our recompilation:

root@ubuntu:/opt/nginx-1.10.1# ./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --sbin-path=/usr/sbin/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_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/opt/nginx-push-stream-module

The MakeFile created by ./configure lives in /opt/nginx-1.10.1/objs/. If everything worked correctly, ngx-http-push-stream-module.c and ngx-http-push-stream-module.o will be referenced in the MakeFile.

Finish things up:

root@ubuntu:/opt/nginx-1.10.1# make
root@ubuntu:/opt/nginx-1.10.1# make install

Start Nginx and check the version and compile flags:

root@ubuntu:/opt/nginx-1.10.1# /etc/init.d/nginx start
[ ok ] Starting nginx (via systemctl): nginx.service.
root@ubuntu:/opt/nginx-1.10.1# nginx -V
nginx version: nginx/1.10.1
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.1)
built with OpenSSL 1.0.2g-fips  1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security 
-Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' 
--prefix=/usr/share/nginx --sbin-path=/usr/sbin/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_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module 
--with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail 
--with-mail_ssl_module --with-threads --add-module=/opt/nginx-push-stream-module

What we've effectively done here is to compile a drop-in replacement for the nginx binary supplied from the Ubuntu main repos. Our new binary lives in the same location as the old one -- /usr/sbin/nginx -- and runs from the /etc/init.d/nginx startup file with no changes. The paths to the lock and log files, and the default config directory, are also the same as before.

Next, we probably want to lock Nginx so the package manager won't overwrite our custom binary:

root@ubuntu:/opt/nginx-1.10.1# apt-mark hold nginx
nginx set on hold.

Finally, we can test our module, per the push-stream documentation.

root@ubuntu:/opt/nginx-push-stream-module/misc# NGINX_PUSH_STREAM_MODULE_PATH=/opt/nginx-push-stream-module
root@ubuntu:/opt/nginx-push-stream-module/misc# nginx -c $NGINX_PUSH_STREAM_MODULE_PATH/misc/nginx.conf -t
nginx: the configuration file /opt/nginx-push-stream-module/misc/nginx.conf syntax is ok
nginx: configuration file /opt/nginx-push-stream-module/misc/nginx.conf test is successful

[In our configuration, the nginx-push-stream-module/misc/nginx.conf file requires a few tweaks to pass, but that's not really the point here. The point is that Nginx recognizes our module.]

Method 2: Recompile Nginx from the Nginx PPA

The procedure here is largely as before, but we're specifying a different version of Nginx.

Add the Nginx Mainline PPA:

root@ubuntu:/# add-apt-repository ppa:nginx/development

Let's see what's available:

root@ubuntu:/# apt-cache madison nginx
     nginx | 1.11.2-0+xenial0 | http://ppa.launchpad.net/nginx/development/ubuntu xenial/main amd64 Packages
     nginx | 1.11.2-0+xenial0 | http://ppa.launchpad.net/nginx/development/ubuntu xenial/main i386 Packages
     nginx | 1.10.0-0ubuntu0.16.04.2 | http://us.archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages
     nginx | 1.10.0-0ubuntu0.16.04.2 | http://us.archive.ubuntu.com/ubuntu xenial-updates/main i386 Packages
     nginx | 1.10.0-0ubuntu0.16.04.2 | http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages
     nginx | 1.10.0-0ubuntu0.16.04.2 | http://security.ubuntu.com/ubuntu xenial-security/main i386 Packages
     nginx | 1.9.15-0ubuntu1 | http://us.archive.ubuntu.com/ubuntu xenial/main amd64 Packages
     nginx | 1.9.15-0ubuntu1 | http://us.archive.ubuntu.com/ubuntu xenial/main i386 Packages

Get the latest Nginx mainline version, and check our compiler flags:

root@ubuntu:/# apt-get install nginx=1.11.2-0+xenial
root@ubuntu:/# nginx -V
nginx version: nginx/1.11.2
built with OpenSSL 1.0.2g-fips  1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security 
-Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' 
--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_gunzip_module 
--with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module 
--with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module 
--with-threads --add-module=/build/nginx-EdIIgW/nginx-1.11.2/debian/modules/nginx-auth-pam 
--add-module=/build/nginx-EdIIgW/nginx-1.11.2/debian/modules/nginx-dav-ext-module 
--add-module=/build/nginx-EdIIgW/nginx-1.11.2/debian/modules/nginx-echo 
--add-module=/build/nginx-EdIIgW/nginx-1.11.2/debian/modules/nginx-upstream-fair 
--add-module=/build/nginx-EdIIgW/nginx-1.11.2/debian/modules/ngx_http_substitutions_filter_module

Grab the latest source code and our push-stream module:

root@ubuntu:/opt# wget http://nginx.org/download/nginx-1.11.3.tar.gz
root@ubuntu:/opt# tar -xvzf nginx-1.11.3.tar.gz
root@ubuntu:/opt# git clone http://github.com/wandenberg/nginx-push-stream-module.git

Install some dependencies:

root@ubuntu:/# apt-get install libpcre3-dev libssl-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev

Recompile Nginx:

root@ubuntu:/opt/nginx-1.11.3# ./configure --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' --prefix=/usr/share/nginx --sbin-path=/usr/sbin/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_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module --with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail --with-mail_ssl_module --with-threads --add-module=/opt/nginx-push-stream-module

Note: if you want to retain the other modules added in by add-module above, you can snag them from the Nginx wiki. I haven't bothered here in the interest of saving time.

As before, our MakeFile lives in /opt/nginx-1.11.3/objs/. Let's finish things up:

root@ubuntu:/opt/nginx-1.11.3# make
root@ubuntu:/opt/nginx-1.11.3# make install

Start up Nginx and check our new compiler flags:

root@ubuntu:/opt/nginx-1.11.3# /etc/init.d/nginx start
[ ok ] Starting nginx (via systemctl): nginx.service.
root@ubuntu:/opt/nginx-1.11.3# nginx -V
nginx version: nginx/1.11.3
built by gcc 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.1)
built with OpenSSL 1.0.2g-fips  1 Mar 2016
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -fPIE -fstack-protector-strong -Wformat -Werror=format-security 
-Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -fPIE -pie -Wl,-z,relro -Wl,-z,now' 
--prefix=/usr/share/nginx --sbin-path=/usr/sbin/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_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_v2_module 
--with-http_sub_module --with-http_xslt_module --with-stream --with-stream_ssl_module --with-mail 
--with-mail_ssl_module --with-threads --add-module=/opt/nginx-push-stream-module

Finally, we probably want to lock Nginx so the package manager won't overwrite our custom binary:

root@ubuntu:/opt/nginx-1.11.3# apt-mark hold nginx
nginx set on hold.

Categories: