Nginx (pronounced “engine x”) is an open-source web server designed for high concurrency. It serves multiple purposes such as an HTTP/HTTPS server, reverse proxy server, mail proxy server, software load balancer, TLS terminator, and caching server.
Nginx is highly modular. Even components like GZIP and SSL, which might appear as default features, are implemented as modules that can be enabled or disabled during build time.
With a C language foundation, Nginx is a fast and lightweight software. It features core modules (native) and a variety of third-party modules created by the community. Currently, there are over a hundred third-party modules available, enabling extensive functionality.
Installing Nginx from source is straightforward—download the latest source version, configure, build, and install it. Decide between downloading the mainline or stable version, as the build process is the same for both.
This guide uses the mainline version 1.15.8. Update version numbers as newer versions are released.
Stable vs. Mainline Version
Nginx Open Source offers two versions:
- Mainline: Features the latest additions and bug fixes. It is highly reliable but may contain experimental modules and potential new bugs.
- Stable: Focuses on reliability, incorporating critical bug fixes found in the mainline version without including all the latest features.
Core Modules vs. Third-party Modules
Two types of modules can enhance Nginx functionality:
- Core Modules: Developed by the Nginx team and included directly in the software.
- Third-party Modules: Community-built extensions providing additional features. Notable examples include PageSpeed, ModSecurity, RTMP, and Lua.
Static Modules vs. Dynamic Modules
Initially, Nginx only supported static modules. Dynamic modules were introduced in Nginx 1.9.11+ (February 2016). Static modules are fixed at compile time with the ./configure
script using --with-foo_bar_module
or --add-module=PATH
.
To compile core modules dynamically, use =dynamic
, e.g., --with-http_image_filter_module=dynamic
. For third-party modules, use --add-dynamic-module=/path/to/module
and load them with the load_module
directive in the nginx.conf
file.
Requirements for Building Nginx from Source
Nginx is lightweight compared to other UNIX/Linux software, with only three mandatory library dependencies:
- OpenSSL/LibreSSL/BoringSSL,
- Zlib,
- PCRE.
Libraries and versions required:
- GCC
- OpenSSL or compatible libraries (versions 1.0.2-1.1.1)
- Zlib (versions 1.1.3-1.2.11)
- PCRE (versions 4.4-8.42)
Optional requirements include:
- Perl
- LibGD
- MaxMind GeoIP Legacy C Library
- libxml2, libxslt
Requirements
- A server running Debian 9 (stretch).
- A non-root user with sudo privileges.
Initial Steps
Check the Debian version:
lsb_release -ds
Install necessary packages:
apt install -y wget curl sudo
Set up the timezone:
sudo dpkg-reconfigure tzdata
Update system packages:
apt update && apt upgrade -y
Build Nginx from Source
Nginx is written in C, so install compiler tools first:
sudo apt install -y build-essential git tree software-properties-common dirmngr apt-transport-https ufw
Download the latest Nginx mainline version source and extract it:
wget https://nginx.org/download/nginx-1.15.8.tar.gz && tar zxvf nginx-1.15.8.tar.gz
Fetch mandatory Nginx dependencies and extract:
wget https://ftp.pcre.org/pub/pcre/pcre-8.42.tar.gz && tar xzvf pcre-8.42.tar.gz
wget https://www.zlib.net/zlib-1.2.11.tar.gz && tar xzvf zlib-1.2.11.tar.gz
wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz && tar xzvf openssl-1.1.1a.tar.gz
Install optional dependencies:
sudo apt install -y perl libperl-dev libgd3 libgd-dev libgeoip1 libgeoip-dev geoip-bin libxml2 libxml2-dev libxslt1.1 libxslt1-dev
Remove temporary files:
rm -rf *.tar.gz
Enter Nginx source directory:
cd ~/nginx-1.15.8
List source directories and files:
tree -L 2 .
Copy Nginx manual page:
sudo cp ~/nginx-1.15.8/man/nginx.8 /usr/share/man/man8
sudo gzip /usr/share/man/man8/nginx.8
ls /usr/share/man/man8/ | grep nginx.8.gz
man nginx
Explore Nginx compile options:
./configure --help
./configure --help | grep -F =dynamic
Configure, compile, and install Nginx:
./configure --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 \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/run/nginx.lock \
--user=nginx \
--group=nginx \
--build=Debian \
--builddir=nginx-1.15.8 \
--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 \
--with-http_perl_module=dynamic \
--with-perl_modules_path=/usr/share/perl/5.24.1 \
--with-perl=/usr/bin/perl \
--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.42 \
--with-pcre-jit \
--with-zlib=../zlib-1.2.11 \
--with-openssl=../openssl-1.1.1a \
--with-openssl-opt=no-nextprotoneg \
--with-debug
make
sudo make install
Return to the home directory:
cd ~
Symlink /usr/lib/nginx/modules
to /etc/nginx/modules
:
sudo ln -s /usr/lib/nginx/modules /etc/nginx/modules
Display Nginx version and configuration details:
sudo nginx -V
nginx version: nginx/1.15.8 (Debian)
built by gcc 6.3.0 (Debian 6.3.0-18+deb9u1)
built with OpenSSL 1.1.1a 20 Nov 2018
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules
Create Nginx system group and user:
sudo adduser --system --home /nonexistent --shell /bin/false --no-create-home --disabled-login --disabled-password --gecos "nginx user" --group nginx
Check Nginx syntax for errors:
sudo nginx -t
# Fix errors by creating required directories:
sudo mkdir -p /var/cache/nginx/client_temp /var/cache/nginx/fastcgi_temp /var/cache/nginx/proxy_temp /var/cache/nginx/scgi_temp /var/cache/nginx/uwsgi_temp
sudo chmod 700 /var/cache/nginx/*
sudo chown nginx:root /var/cache/nginx/*
sudo nginx -t
Create Nginx systemd unit file:
sudo vim /etc/systemd/system/nginx.service
Copy and paste the following into the file:
[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
Enable and start Nginx:
sudo systemctl enable nginx.service
sudo systemctl start nginx.service
Verify Nginx auto-start after reboot:
sudo systemctl is-enabled nginx.service
Check Nginx operation status:
sudo systemctl status nginx.service
# or
ps aux | grep nginx
#or
curl -I 127.0.0.1
Access your domain or IP via browser to see the default Nginx page, indicating it is functional.
Create a UFW Nginx application profile:
sudo vim /etc/ufw/applications.d/nginx
Add the following:
[nginx HTTP]
title=Web Server (nginx, HTTP)
description=Small, but very powerful and efficient web server
ports=80/tcp
[nginx HTTPS]
title=Web Server (nginx, HTTPS)
description=Small, but very powerful and efficient web server
ports=443/tcp
[nginx Full]
title=Web Server (nginx, HTTP + HTTPS)
description=Small, but very powerful and efficient web server
ports=80,443/tcp
Verify UFW profiles:
sudo ufw app list
# Available applications:
# nginx Full
# nginx HTTP
# nginx HTTPS
Remove default backups:
sudo rm /etc/nginx/*.default
Enable syntax highlighting in Vim:
mkdir ~/.vim/
cp -r ~/nginx-1.15.8/contrib/vim/* ~/.vim/
# For root user
sudo mkdir /root/.vim/
sudo cp -r ~/nginx-1.15.8/contrib/vim/* /root/.vim/
Create essential directories in /etc/nginx
:
sudo mkdir /etc/nginx/{conf.d,snippets,sites-available,sites-enabled}
Set log file permissions:
sudo chmod 640 /var/log/nginx/*
sudo chown nginx:adm /var/log/nginx/access.log /var/log/nginx/error.log
Configure log rotation:
sudo vim /etc/logrotate.d/nginx
Add the following configuration:
/var/log/nginx/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 nginx adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
Clean up source files:
cd ~
rm -rf nginx-1.15.8/ openssl-1.1.1a/ pcre-8.42/ zlib-1.2.11/
Installation is complete. You now have the latest Nginx version built from source, optimized for critical libraries like OpenSSL. This installation method allows leveraging new ciphers like CHACHA20_POLY1305
and protocols such as TLS 1.3 available with OpenSSL 1.1.1
.
Frequently Asked Questions (FAQ)
Q1: Why build Nginx from source?
By building from source, you can customize your Nginx installation with specific modules and features tailored to your needs, ensuring compatibility with the latest libraries and security protocols.
Q2: Are there any risks of using the mainline version?
The mainline version is stable but may contain experimental features. It is essential to test configurations thoroughly in a non-production environment before deployment.
Q3: What should I do if I encounter errors during the build process?
Double-check that all dependencies are installed and that you followed the steps correctly. Consider reviewing error logs for more detail and consult the Nginx documentation for further assistance.
Q4: How often should I update Nginx?
Regular updates are recommended to leverage improvements and patch vulnerabilities. Always follow the latest security advisories and update accordingly.
Q5: Can I add more third-party modules?
Yes, you can integrate additional third-party modules by adjusting the configuration steps to include their respective source paths during compilation.