← Back to blog
Nginx Upstream Health Check Without Nginx Plus: Step-by-Step Guide
LinuxNginx

Nginx Upstream Health Check Without Nginx Plus: Step-by-Step Guide

Learn how to add upstream health checks to open-source Nginx by compiling nginx_upstream_check_module from source and building a .deb package on Ubuntu 24.04.

April 2, 20264 min read

Adding Upstream Check to Free Nginx

Since the upstream availability check feature in Nginx is only available in the commercial version, </br> we’ll compile Nginx with the open-source nginx_upstream_check_module module to achieve nearly the same functionality.

Since packages built from source code are difficult to update, we’ll build a DEB package and install Nginx from the DEB packages.</br> The modules and dependencies required for Nginx to run will be automatically installed.

Let's check if Nginx is installed on the system and which repository it comes from:

sh
root@skillmachines:~ apt-cache policy nginx
nginx:
  Installed: 1.24.0-2ubuntu7.3
  Candidate: 1.24.0-2ubuntu7.3
  Version table:
 *** 1.24.0-2ubuntu7.3 500
        500 http://security.ubuntu.com/ubuntu noble-security/main amd64 Packages

If installed, remove it along with the configuration files

sh
apt purge nginx

What to do:

Add the source code repository

Our virtual machine runs on Ubuntu 24.04. The source code repositories are not enabled, so to download the </br>Nginx source code and install all dependencies, we need to create a deb-src repository file. Open repository config:

sh
vim /etc/apt/sources.list.d/deb-src.list

Add these lines:

sh
deb-src http://archive.ubuntu.com/ubuntu/ noble main restricted
deb-src http://archive.ubuntu.com/ubuntu/ noble-updates main restricted
deb-src http://security.ubuntu.com/ubuntu/ noble-security main restricted

Download the nginx source code

Update the package list, install the dependencies needed to compile from source, 'cd' to the directory where</br> we will compile Nginx, and download the source code:

sh
apt update 
apt build-dep nginx 
cd /opt
apt source nginx

After executing the commands, we should see the source code:

sh
root@skillmachines:/opt ls -1
nginx-1.24.0
nginx_1.24.0-2ubuntu7.4.debian.tar.xz
nginx_1.24.0-2ubuntu7.4.dsc
nginx_1.24.0.orig.tar.gz

Download the upstream_check_module patch files

sh
git clone https://github.com/yaoweibin/nginx_upstream_check_module

Let’s add the nginx_upstream_check_module module to the Nginx build. In addition to the source code itself,</br> the source files also contain instructions for building a Debian package, which is certainly helpful for us.</br> All instructions are stored in the file nginx-1.24.0/debian/rules. We need to find the line in this file with the arguments for running ./configure</br> and add our module. Open file:

sh
nginx-1.24.0/debian/rules

Add our module to the end of the file:

sh
basic_configure_flags := \
                        --prefix=/usr/share/nginx \
                        --conf-path=/etc/nginx/nginx.conf \
                        --http-log-path=/var/log/nginx/access.log \
                        --error-log-path=stderr \
                        --lock-path=/var/lock/nginx.lock \
                        --pid-path=/run/nginx.pid \
                        --modules-path=/usr/lib/nginx/modules \
                        --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-compat \
                        --with-debug \
                        --with-pcre-jit \
                        --with-http_ssl_module \
                        --with-http_stub_status_module \
                        --with-http_realip_module \
                        --with-http_auth_request_module \
                        --with-http_v2_module \
                        --with-http_dav_module \
                        --with-http_slice_module \
                        --with-threads \
                        --add-module=/opt/nginx_upstream_check_module/

In other versions of Nginx, the syntax of the configuration file is slightly different </br> nginx-<version>/debian/rules</br> line </br> CFLAGS= </br> Add the following argument at the end </br> --add-module=/opt/nginx_upstream_check_module </br> example:

txt
config.status.nginx: config.env.nginx
  cd $(BUILDDIR_nginx) && \
  CFLAGS="" ./configure  ....  --add-module=/opt/nginx_upstream_check_module
  touch $@

and add in config.status.nginx_debug: config.env.nginx_debug

Patch nginx

Nginx_upstream_check_module requires applying patches, as described in its README. You should choose the patch file based on your version of Nginx, </br>but in our case, there isn't a patch available for our version. Let's choose the most recent one.

sh
ls -1 /opt/nginx_upstream_check_module/*.patch
sh
cd /opt/nginx-1.24.0/
patch -p1 < /opt/nginx_upstream_check_module/check_1.20.1+.patch

Build a deb package

You can now proceed to building the deb packages:

sh
cd /opt/nginx-1.24.0/
dpkg-buildpackage -b --no-sign

After a lengthy build, you will end up with a large number of Nginx DEB packages. The build will result in new files in the parent directory</br> (since we were building from the /opt/nginx-1.24.0 directory)

Let’s check if the installation DEB packages were successfully built:

txt
# ls -1 /opt/*.deb
/opt/libnginx-mod-http-geoip_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-http-image-filter_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-http-perl_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-http-xslt-filter_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-mail_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-stream-geoip_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-stream_1.24.0-2ubuntu7.4_amd64.deb
/opt/nginx-common_1.24.0-2ubuntu7.4_all.deb
/opt/nginx-core_1.24.0-2ubuntu7.4_all.deb
/opt/nginx-dev_1.24.0-2ubuntu7.4_all.deb
/opt/nginx-doc_1.24.0-2ubuntu7.4_all.deb
/opt/nginx-extras_1.24.0-2ubuntu7.4_amd64.deb
/opt/nginx-full_1.24.0-2ubuntu7.4_all.deb
/opt/nginx-light_1.24.0-2ubuntu7.4_all.deb
/opt/nginx_1.24.0-2ubuntu7.4_amd64.deb

module

txt
# ls -1 /opt/libnginx-mod-*.deb
/opt/libnginx-mod-http-geoip_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-http-image-filter_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-http-perl_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-http-xslt-filter_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-mail_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-stream-geoip_1.24.0-2ubuntu7.4_amd64.deb
/opt/libnginx-mod-stream_1.24.0-2ubuntu7.4_amd64.deb

Install nginx

Install Nginx from DEB packages.

sh
dpkg -i /opt/nginx-common_1.24.0-2ubuntu7.4_all.deb
dpkg -i /opt/nginx_1.24.0-2ubuntu7.4_amd64.deb
dpkg -i /opt/nginx-dev_1.24.0-2ubuntu7.4_all.deb

install lib module

sh
dpkg -i /opt/libnginx-mod-*.deb

Let's check the installed version of nginx and modules using the following commands:

sh
nginx -v
nginx -V 2>&1 | xargs -n1 | grep module

Freeze the current nginx version

sh
apt-mark hold nginx

Result config:

nginx
http {
    upstream backend {
        server 10.0.0.1:8080;
        server 10.0.0.2:8080;

        check interval=3000 rise=2 fall=3 timeout=1000 type=http;
        check_http_send "HEAD /health HTTP/1.0\r\n\r\n";
        check_http_expect_alive http_2xx http_3xx;
    }

    server {
        listen 80;

        location / {
            proxy_pass http://backend;
        }

        location /upstream_status {
            check_status;
            access_log off;
            allow 127.0.0.1;
            deny all;
        }
    }
}

Verify it works

shell
# check module
nginx -V 2>&1 | xargs -n1 | grep upstream_check

nginx -t && systemctl reload nginx

# Check upstream statuses
curl http://localhost/upstream_status

Now Nginx will automatically exclude unhealthy backends from the rotation and bring them back once they recover - without any manual intervention. The /upstream_status page gives you a quick overview of the current state of all upstreams, which is useful for debugging and monitoring.

Subscribe for new tasks and project news

No spam. Only project information.