How to Compile Nginx From Source on CentOS 7
NGINX can be used as an HTTP/HTTPS server, reverse proxy server, mail proxy server, load balancer, TLS terminator, or caching server. It is quite modular by design. It has native modules and third-party modules created by the community. Written in the C programming language, it's a very fast and lightweight piece of software.
NOTE: NGINX has two version streams that run in parallel - stable and mainline. Both versions can be used on a production server. It is recommended to use the mainline version in production.
Installing NGINX from source code is relatively "easy" - download the latest version of the NGINX source code, configure, build and install it.
In this tutorial, I will use the mainline version, which is 1.13.2 at the time of writing. Update version numbers accordingly when newer versions become available.
Requirements for building NGINX from source
Mandatory requirements:
- OpenSSL library version between 1.0.2 - 1.1.0
- zlib library version between 1.1.3 - 1.2.11
- PCRE library version between 4.4 - 8.40
- GCC Compiler
Optional requirements:
Before you begin
Create regular user with
sudo
access.Switch to the new user:
su - <username>
Update system:
sudo yum check-update || sudo yum update -y
Build NGINX from source
Install "Development Tools" and Vim editor:
sudo yum groupinstall -y 'Development Tools' && sudo yum install -y vim
Install Extra Packages for Enterprise Linux (EPEL):
sudo yum install -y epel-release
Download and install optional NGINX dependencies:
sudo yum install -y perl perl-devel perl-ExtUtils-Embed libxslt libxslt-devel libxml2 libxml2-devel gd gd-devel GeoIP GeoIP-devel
Download the latest mainline version of NGINX source code and extract it:
wget https://nginx.org/download/nginx-1.13.2.tar.gz && tar zxvf nginx-1.13.2.tar.gz
Download the NGINX dependencies' source code and extract them:
# PCRE version 8.40 wget https://ftp.pcre.org/pub/pcre/pcre-8.40.tar.gz && tar xzvf pcre-8.40.tar.gz # zlib version 1.2.11 wget https://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz # OpenSSL version 1.1.0f wget https://www.openssl.org/source/openssl-1.1.0f.tar.gz && tar xzvf openssl-1.1.0f.tar.gz
Remove all
.tar.gz
files. We don't need them anymore:rm -rf *.tar.gz
Go to the NGINX source directory:
cd ~/nginx-1.13.2
For good measure, list nginx source code files and directories:
ls # auto CHANGES CHANGES.ru conf configure contrib html LICENSE man README src
Copy NGINX manual page to
/usr/share/man/man8
:sudo cp ~/nginx-1.13.2/man/nginx.8 /usr/share/man/man8 sudo gzip /usr/share/man/man8/nginx.8 # Check that Man page for NGINX is working man nginx
For help, you can list the available configuration switches by running:
./configure --help # To see want core modules can be build as dynamic run: ./configure --help | grep -F =dynamic
Configure, compile, and install NGINX:
./configure --prefix=/etc/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 \ --pid-path=/var/run/nginx.pid \ --lock-path=/var/run/nginx.lock \ --user=nginx \ --group=nginx \ --build=CentOS \ --builddir=nginx-1.13.2 \ --with-select_module \ --with-poll_module \ --with-threads \ --with-file-aio \ --with-http_ssl_module \ --with-http_v2_module \ --with-http_realip_module \ --with-http_addition_module \ --with-http_xslt_module=dynamic \ --with-http_image_filter_module=dynamic \ --with-http_geoip_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_auth_request_module \ --with-http_random_index_module \ --with-http_secure_link_module \ --with-http_degradation_module \ --with-http_slice_module \ --with-http_stub_status_module \ --http-log-path=/var/log/nginx/access.log \ --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 \ --with-mail=dynamic \ --with-mail_ssl_module \ --with-stream=dynamic \ --with-stream_ssl_module \ --with-stream_realip_module \ --with-stream_geoip_module=dynamic \ --with-stream_ssl_preread_module \ --with-compat \ --with-pcre=../pcre-8.40 \ --with-pcre-jit \ --with-zlib=../zlib-1.2.11 \ --with-openssl=../openssl-1.1.0f \ --with-openssl-opt=no-nextprotoneg \ --with-debug make sudo make install
Symlink
/usr/lib64/nginx/modules
to/etc/nginx/modules
directory, so that you can load dynamic modules in nginx configuration like thisload_module modules/ngx_foo_module.so;
:sudo ln -s /usr/lib64/nginx/modules /etc/nginx/modules
Print the NGINX version, compiler version, and configure script parameters:
sudo nginx -V # nginx version: nginx/1.13.2 (CentOS) # built by gcc 4.8.5 20150623 (Red Hat 4.8.5-11) (GCC) # built with OpenSSL 1.1.0f 25 May 2017 # TLS SNI support enabled # configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx . . . # . . . # . . .
Create the NGINX system user and group:
sudo useradd --system --home /var/cache/nginx --shell /sbin/nologin --comment "nginx user" --user-group nginx
Check syntax and potential errors:
sudo nginx -t # Will throw this error: nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (2: No such file or directory) # Just create directory sudo mkdir -p /var/cache/nginx && sudo nginx -t
Create a systemd unit file for nginx:
sudo vim /usr/lib/systemd/system/nginx.service
Copy/paste the following content:
NOTE: The location of the PID file and the NGINX binary may be different depending on how NGINX was compiled.
[Unit] Description=nginx - high performance web server Documentation=https://nginx.org/en/docs/ After=network-online.target remote-fs.target nss-lookup.target Wants=network-online.target [Service] Type=forking PIDFile=/var/run/nginx.pid ExecStartPre=/usr/sbin/nginx -t -c /etc/nginx/nginx.conf ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf ExecReload=/bin/kill -s HUP $MAINPID ExecStop=/bin/kill -s TERM $MAINPID [Install] WantedBy=multi-user.target
Start and enable the NGINX service:
sudo systemctl start nginx.service && sudo systemctl enable nginx.service
Check if NGINX will startup after a reboot:
sudo systemctl is-enabled nginx.service # enabled
Check if NGINX is running:
sudo systemctl status nginx.service ps aux | grep nginx curl -I 127.0.0.1
Reboot your VPS to verify that NGINX starts up automatically:
sudo shutdown -r now
Remove archaic files from the
/etc/nginx
directory:sudo rm /etc/nginx/koi-utf /etc/nginx/koi-win /etc/nginx/win-utf
Place syntax highlighting of NGINX configuration for
vim
into~/.vim/
. You will get nice syntax highlighting when editing NGINX configuration file:mkdir ~/.vim/ cp -r ~/nginx-1.13.2/contrib/vim/* ~/.vim/
Remove all
.default
backup files from/etc/nginx/
:sudo rm /etc/nginx/*.default
Conclusion
That's it. You now have newest version of NGINX installed. It is compiled statically against some important libraries like OpenSSL. Often, the system OpenSSL version is outdated. By using this method of installing with a newer version of OpenSSL, you can take advantage of new ciphers like CHACHA20_POLY1305
and protocols like TLS 1.3 that will be available in OpenSSL 1.1.1
(which has not been released at the time of writing).