How to setup Pagespeed module in Nginx using rpm or yum on CentOS 7

Adding Pagespeed module in Apache is very easy with package manager:


sudo yum install at # if you do not already have 'at' installed
sudo rpm -U mod-pagespeed-*.rpm

... but if we want to add Pagespeed module in Nginx, first thing we think of is compiling its source along with the Pagespeed module. What if Nginx is installed in our server from yum or rpm? The process we need is to repackage RPM and that is what this tutorial will show.

Prepare tools

The following procedures are tested on my Linode server running Centos 7 64-bit Linux distribution.

  1. First we need to install the necessary tools to repackage RPM:
    
    sudo yum install gcc-c++ pcre-devel zlib-devel make unzip wget openssl-devel libxml2-devel libxslt-devel gd-devel perl-ExtUtils-Embed GeoIP-devel gperftools-devel rpm-build redhat-lsb-core libuuid-devel
    
    
  2. It is recommended to not to use root user in building RPM, so we will create a new user:
    
    useradd -m builder
    
    

    * The -m is to create home directory

  3. Select the latest version of Nginx RPM source here and download (as of this writing the latest is nginx-1.10.3-1.el7.ngx.src.rpm):
    
    rpm -Uvh http://nginx.org/packages/centos/7/SRPMS/nginx-1.14.2-1.el7_4.ngx.src.rpm
    
    
  4. Move the Nginx RPM source to the new user created "builder" home directory:
    
    mv /root/rpmbuild /home/builder/ && chown -R builder. /home/builder/rpmbuild
    
    

Pagespeed source

  1. Login as "builder" and go to RPM source directory:
    
    su builder
    cd ~/rpmbuild/SOURCES/
    
    
  2. Download and extract the latest version of Pagespeed (you can verify the latest version here):
    
    NPS_VERSION=1.13.35.2-stable
    wget https://github.com/pagespeed/ngx_pagespeed/archive/v${NPS_VERSION}.zip
    unzip v${NPS_VERSION}.zip
    rm v${NPS_VERSION}.zip
    
    
  3. Inside the extracted Pagespeed source directory, download and extract its required PSOL library:
    
    nps_dir=$(find . -name "*pagespeed-ngx-${NPS_VERSION}" -type d)
    cd "$nps_dir"
    NPS_RELEASE_NUMBER=${NPS_VERSION/beta/}
    NPS_RELEASE_NUMBER=${NPS_VERSION/stable/}
    psol_url=https://dl.google.com/dl/page-speed/psol/${NPS_RELEASE_NUMBER}.tar.gz
    [ -e scripts/format_binary_url.sh ] && psol_url=$(scripts/format_binary_url.sh PSOL_BINARY_URL)
    wget ${psol_url}
    tar -xzvf $(basename ${psol_url})
    rm $(basename ${psol_url})
    
    
  4. Archive both Pagespeed and PSOL as one:
    
    cd ..
    tar -zcvf incubator-pagespeed-ngx-1.13.35.2-stable.tar.gz incubator-pagespeed-ngx-1.13.35.2-stable/
    rm -r incubator-pagespeed-ngx-1.13.35.2-stable/
    cd ~
    
    

Enable Pagespeed in Nginx spec

  1. Open and edit "nginx.spec" file:
    
    vi ~/rpmbuild/SPECS/nginx.spec
    
    
  2. Search for %define main_release 1%{?dist}.ngx and add the following line below it:

    
    %define pagespeed_version 1.13.35.2-stable
    
    

    Note: '1.13.35.2-stable" is the version of Pagespeed.

    Its section should look something like this:

      
    %define main_version 1.14.2
    %define main_release 1%{?dist}.ngx
    %define pagespeed_version 1.13.35.2-stable
      
    
  3. Scroll down and search --with-stream_ssl_preread_module and add the following line beside it:

    
    --add-module=%{_builddir}/%{name}-%{main_version}/incubator-pagespeed-ngx-%{pagespeed_version}
    
    

    Its section should look something like this:

    
    %define BASE_CONFIGURE_ARGS $(echo "--prefix=%{_sysconfdir}/nginx --sbin-path=%{_sbindir}/nginx --modules-path=%{_libdir}/nginx/modules --conf-path=%{_sysconfdir}/nginx/nginx.conf --error-log-path=%{_localstatedir}/log/nginx/error.log --http-log-path=%{_localstatedir}/log/nginx/access.log --pid-path=%{_localstatedir}/run/nginx.pid --lock-path=%{_localstatedir}/run/nginx.lock --http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp --http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp --http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp --http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp --user=%{nginx_user} --group=%{nginx_group} --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --add-module=%{_builddir}/%{name}-%{main_version}/incubator-pagespeed-ngx-%{pagespeed_version}")
    
    
  4. Again scroll down and search Source13: nginx.check-reload.sh and add the following line under it:

    
    Source14: incubator-pagespeed-ngx-%{pagespeed_version}.tar.gz
    
    

    Its section should look something like this:

    
    Source0: http://nginx.org/download/%{name}-%{version}.tar.gz
    Source1: logrotate
    Source2: nginx.init.in
    Source3: nginx.sysconf
    Source4: nginx.conf
    Source5: nginx.vh.default.conf
    Source7: nginx-debug.sysconf
    Source8: nginx.service
    Source9: nginx.upgrade.sh
    Source10: nginx.suse.logrotate
    Source11: nginx-debug.service
    Source12: COPYRIGHT
    Source13: nginx.check-reload.sh
    Source14: incubator-pagespeed-ngx-%{pagespeed_version}.tar.gz
    
    
  5. And scroll down and search %setup -q and add the following lines under it:

    
    tar zxvf %SOURCE14
    %setup -T -D -a 14
    
    

    Note: The 14 in %setup -T -D -a 14 above came from SOURCE14.

    Its section should look something like this:

    
    %prep
    %setup -q
    tar zxvf %SOURCE14
    %setup -T -D -a 14
    cp %{SOURCE2} .
    sed -e 's|%%DEFAULTSTART%%|2 3 4 5|g' -e 's|%%DEFAULTSTOP%%|0 1 6|g' \
        -e 's|%%PROVIDES%%|nginx|g'  nginx.init
    sed -e 's|%%DEFAULTSTART%%||g' -e 's|%%DEFAULTSTOP%%|0 1 2 3 4 5 6|g' \
        -e 's|%%PROVIDES%%|nginx-debug|g'  nginx-debug.init
    
    
  6. (Optional) By default, the Nginx debugging log is enabled. If you want disabled it, scroll down and search --with-debug and remove --with-debug. Its section should look something like this after removing it:

    
    %build
    ./configure %{BASE_CONFIGURE_ARGS} \
        --with-cc-opt="%{WITH_CC_OPT}" \
        --with-ld-opt="%{WITH_LD_OPT}" 
    
    
  7. And save the nginx.spec file.

Build and install the new Nginx with Pagespeed module

  1. Build the Nginx RPM package:

      
    rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec
      
    

    When I executed it, I got the following error:

      
    sh: lsb_release: command not found
    error: /home/builder/rpmbuild/SPECS/nginx.spec:28: bad %if condition
      
    

    To fix it, we need to find and install the package that provides lsb_release command as "root" user:

      
    yum provides */lsb_release
    yum install redhat-lsb-core
      
    

    Run again the command to build the Nginx RPM package:

      
    su builder
    rpmbuild -ba ~/rpmbuild/SPECS/nginx.spec
      
    

    If you got the following error after executing it:

      
    checking for psol ... not found
    ./configure: error: module ngx_pagespeed requires the pagespeed optimization library.
      
    

    ... install libuuid-devel as "root" user to fix it:

      
    yum install libuuid-devel
      
    

    If you did not remove the Nginx debugging log, you will be prompted by the following message. Just type "Y" and hit Enter.

    
    You have set --with-debug for building nginx, but precompiled Debug binaries for
    PSOL, which ngx_pagespeed depends on, aren't available.  If you're trying to
    debug PSOL you need to build it from source.  If you just want to run nginx with
    debug-level logging you can use the Release binaries.
    
    Use the available Release binaries? [Y/n] Y
    
    

    After the compilation completed you should see output message at the end look something like these:

    
    Wrote: /home/builder/rpmbuild/SRPMS/nginx-1.14.2-1.el7_4.ngx.src.rpm
    Wrote: /home/builder/rpmbuild/RPMS/x86_64/nginx-1.14.2-1.el7_4.ngx.x86_64.rpm
    Wrote: /home/builder/rpmbuild/RPMS/x86_64/nginx-debuginfo-1.14.2-1.el7_4.ngx.x86_64.rpm
    Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.MDf5hy
    + umask 022
    + cd /home/builder/rpmbuild/BUILD
    + cd nginx-1.14.2
    + /usr/bin/rm -rf /home/builder/rpmbuild/BUILDROOT/nginx-1.14.2-1.el7_4.ngx.x86_64
    + exit 0
    
    

    As we can see the Nginx RPM package bundled with Pagespeed is saved in ~/rpmbuild/RPMS/

  2. Login as root in able to install the compiled Nginx RPM:
    
    su
    
    

    You can use yum or rpm to install it:

    
    yum update /home/builder/rpmbuild/RPMS/x86_64/nginx-1.14.2-1.el7_4.ngx.x86_64.rpm
    
    

    ... or:

    
    rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.14.2-1.el7_4.ngx.x86_64.rpm
    
    

    If the current nginx is higher version than we have compiled (like in my case I have nginx v1.14.6), execute the following to force install the Nginx RPM we have build:

    
    yum downgrade /home/builder/rpmbuild/RPMS/x86_64/nginx-1.14.2-1.el7_4.ngx.x86_64.rpm
    
    

    ... or:

    
    rpm -Uvh --oldpackage /home/builder/rpmbuild/RPMS/x86_64/nginx-1.14.2-1.el7_4.ngx.x86_64.rpm
    
    
  3. Make sure it auto-start upon reboot:
    
    chkconfig nginx on
    
    

    To check if Pagespeed is included in Nginx:

    
    nginx -V
    
    

If you don't want to build the RPM in your production server, you may use other machine. In my case, I just build my RPM in a laptop using CentOS 7 64-bit Vagrant box. Just make sure they have both the same system type (OS and processor).

For PageSpeed Nginx configuration, please see this article.

Comments

First of all thank you for this Howto,
But I'm unable to rpmbuild.
I got this message: error : line 83 : unknow tag: --prefix=/etc/nginx \

Any idea?

Thank you

That line should not be changed to --prefix=/etc/nginx \. Please check your ~/rpmbuild/SPECS/nginx.spec and make sure that line look the same as the code below:

--prefix=%{_sysconfdir}/nginx \

I have re-tried the tutorial and it works just fine in my system. I have successfully compiled the nginx+pagespeed without any errors. I suggest to try the whole steps again. Please follow them carefully and don't change anything that is not in the steps above.

Hello,
This morning I brought my Brain,
Everything was fine except that I modified nginx.spec as root, and try to package as builder.

Thank you!

Hi thank you very much for make thus tutorial, hope you add an option to add openssl 1.1.0e
regards,
maszd

when I execute as root:
rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm

i get:
Preparing... ################################# [100%]
package nginx-1:1.12.2-1.el7_4.ngx.x86_64 is already installed
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x8
6_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.
ngx.x86_64

also tried downgrading. How can I fix it?

You can try these two options:
  1. Uninstall and re-install the package:
          
    rpm -e nginx
    rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
          
        
  2. Replace the package that is already installed:
          
    rpm -ivh --replacepkgs /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
          
        

when I execute as root:
rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm

i get:
Preparing... ################################# [100%]
package nginx-1:1.12.2-1.el7_4.ngx.x86_64 is already installed
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x8
6_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.
ngx.x86_64

also tried downgrading. How can I fix it?

not working:

[root@webserver /]# rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
Preparing... ################################# [100%]
package nginx-1:1.12.2-1.el7_4.ngx.x86_64 is already installed
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
[root@webserver /]# systemctl restart webmin
[root@webserver /]# rpm -ivh --replacepkgs /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
Preparing... ################################# [100%]
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
[root@webserver /]# rpm -e nginx
error: Failed dependencies:
nginx is needed by (installed) nginx-mod-http-perl-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-stream-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-http-image-filter-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-http-xslt-filter-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-mail-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-http-geoip-1:1.12.2-1.el7.x86_64
[root@webserver /]# rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
Preparing... ################################# [100%]
package nginx-1:1.12.2-1.el7_4.ngx.x86_64 is already installed
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
[root@webserver /]#

[root@webserver /]# rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
Preparing... ################################# [100%]
package nginx-1:1.12.2-1.el7_4.ngx.x86_64 is already installed
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
[root@webserver /]# systemctl restart webmin
[root@webserver /]# rpm -ivh --replacepkgs /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
Preparing... ################################# [100%]
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
[root@webserver /]# rpm -e nginx
error: Failed dependencies:
nginx is needed by (installed) nginx-mod-http-perl-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-stream-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-http-image-filter-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-http-xslt-filter-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-mail-1:1.12.2-1.el7.x86_64
nginx is needed by (installed) nginx-mod-http-geoip-1:1.12.2-1.el7.x86_64
[root@webserver /]# rpm -Uvh /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
Preparing... ################################# [100%]
package nginx-1:1.12.2-1.el7_4.ngx.x86_64 is already installed
file /usr/sbin/nginx from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
file /usr/sbin/nginx-debug from install of nginx-1:1.12.2-1.el7_4.ngx.x86_64 conflicts with file from package nginx-1:1.12.2-1.el7_4.ngx.x86_64
[root@webserver /]#

It seems you have installed these nginx modules as dynamic modules:
  
nginx-mod-http-perl-1:1.12.2-1.el7.x86_64
nginx-mod-stream-1:1.12.2-1.el7.x86_64
nginx-mod-http-image-filter-1:1.12.2-1.el7.x86_64
nginx-mod-http-xslt-filter-1:1.12.2-1.el7.x86_64
nginx-mod-mail-1:1.12.2-1.el7.x86_64
nginx-mod-http-geoip-1:1.12.2-1.el7.x86_64
  
In the first place, your nginx is already version 1.12.2 why would you install same version? I suggest you keep your existing nginx. Anyway, if you are just experimenting or doing something else first remove the dynamic modules mentioned above. I'm not sure what linux distro you are using but for Red Hat/CentOS systems:
  
yum remove nginx-mod-http-perl
yum remove nginx-mod-stream
yum remove nginx-mod-http-image-filter
yum remove nginx-mod-http-xslt-filter
yum remove nginx-mod-mail
yum remove nginx-mod-http-geoip
  
for Ubuntu/Debian systems:
  
apt-get remove nginx-mod-http-perl
apt-get remove nginx-mod-stream
apt-get remove nginx-mod-http-image-filter
apt-get remove nginx-mod-http-xslt-filter
apt-get remove nginx-mod-mail
apt-get remove nginx-mod-http-geoip
  
Then try installing the nginx you have build and the dynamic modules you have removed (only those modules that you did not compiled with nginx as static modules).

I successfully build the rpm and install it
but when I start the nginx service I got the following error

-- Unit nginx.service has begun starting up.
Feb 28 17:42:11 xxx.com nginx[17451]: /usr/sbin/nginx: error while loading shared libraries: cannot create cache for search path: Cannot allocate memory
Feb 28 17:42:11 xxx.com systemd[1]: nginx.service: control process exited, code=exited status=127
Feb 28 17:42:11 xxx.com systemd[1]: Failed to start nginx - high performance web server.
-- Subject: Unit nginx.service has failed
-- Defined-By: systemd
-- Support: http://lists.freedesktop.org/mailman/listinfo/systemd-devel
--
-- Unit nginx.service has failed.

First, awesome post man, keep doing the good job
but I still can't start nginx:
/usr/sbin/nginx: error while loading shared libraries: cannot create cache for search path: Cannot allocate memory

my /usr/lib/systemd/system/nginx.service:
[Service]
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon off; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon off; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon off; master_process on;' -s reload
ExecStop=/usr/sbin/nginx -s quit

can anyone help with that?

Try to uninstall nginx:

  
yum remove nginx
  

... and re-install it:

  
yum install /home/builder/rpmbuild/RPMS/x86_64/nginx-1.12.2-1.el7.ngx.x86_64.rpm
  

Then start the nginx:

  
service nginx start
  

If you still getting the error, try executing either of the following commands:

  1.       
    /usr/sbin/nginx -t -q -g 'daemon off; master_process on;'
    /usr/sbin/nginx -g 'daemon off; master_process on;'
          
        
  2.       
    /usr/sbin/nginx -t -c /etc/nginx/nginx.conf
          
        

Just wanted to throw in a thanks because I found this guide to be incredibly helpful and precise. While I did get stuck on yum install libuuid-devel which made no difference (I still got psol ... not found) Replacing my "devtoolset-2" with something more recent took care of that.

Thank you so much for this detailed walkthrough the dynamic installation.
I tried the others available online with no success.. all the steps worked i had to be careful over the main_version variable which in my case NGINX 1.20.2 was base_version
simply changing that worked well..

Add new comment

Restricted HTML

  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • Lines and paragraphs break automatically.