Installing HAProxy from source on Oracle Linux 8

In another post I mentioned that I’ve compiled HAProxy from the source code because the one coming with Oracle Linux 8 default repository is still on the version of 1.8.x, here I will talk about how to do that for the version 2.7.9.

Compiling HAProxy from the source code is no different than comipling other Linux software packages. The HAProxy source code (tar.gz) file already contains the Makefile. What need to be done are quite straightforward.

  1. Download the 2.7.9 version. https://www.haproxy.org/download/2.7/src/haproxy-2.7.9.tar.gz
  2. Install required packages for compiling. Need to enable one additional repository though.
  3. Compile and install HAProxy.

To download the source code:

curl https://www.haproxy.org/download/2.7/src/haproxy-2.7.9.tar.gz -o haproxy-2.7.9.tar.gz

Enable/Install the ol8_codeready_builder repository so that we can have lua-devel package installed. This is a repository equivalent to PowerTools on CentOS8 and codeready-builder-for-rhel-8-x86_64-rpms on RHEL 8.

dnf config-manager --enable ol8_codeready_builder

Lua is a lightweight, high-level, multi-paradigm programming language designed primarily for embedded use in applications. HAProxy supports Lua to extend its functionality. To be able to use Lua, we need to build HAProxy with Lua support enabled.

Install the following packages and dnf will resolve all dependencies:

dnf install gcc openssl-devel readline-devel systemd-devel make pcre-devel tar lua lua-devel

unzip and untar the source code, it will create a directory haproxy-2.7.9 under your current directory.

tar xzf haproxy-2.7.9.tar.gz

In this directory, you will see the Makefile. So no need to run “./configure” and there is no configure tool in this source package. Also this is a file called “INSTALL” which has the installation instructions.

Take a look this “INSTALL” file so you understand what to expect. Also you can read the “Makefile” or use

make help
make help TARGET=linux-glibc

to see what features are available and what are enabled/disabled by default for a specfic platform. For example, you will see the following when specifiying the platform “make help TARGET=linux-glibc

Current TARGET: linux-glibc

Enabled features for TARGET 'linux-glibc' (disable with 'USE_xxx=') :
  EPOLL NETFILTER POLL THREAD BACKTRACE TPROXY LINUX_TPROXY LINUX_SPLICE
  LIBCRYPT CRYPT_H GETADDRINFO ACCEPT4 SLZ CPU_AFFINITY TFO NS DL RT
  PRCTL THREAD_DUMP SHM_OPEN

Disabled features for TARGET 'linux-glibc' (enable with 'USE_xxx=1') :
  KQUEUE PCRE PCRE_JIT PCRE2 PCRE2_JIT PTHREAD_EMULATION STATIC_PCRE
  STATIC_PCRE2 ENGINE OPENSSL OPENSSL_WOLFSSL LUA CLOSEFROM ZLIB
  DEVICEATLAS 51DEGREES WURFL SYSTEMD OBSOLETE_LINKER PROCCTL EVPORTS
  OT QUIC PROMEX MEMORY_PROFILING

Meanwhile, check what build options were used for the version 1.8.x provided by Oracle Linux 8:

root@joetest:~/haproxy-2.7.9# haproxy -vv
HA-Proxy version 1.8.27-493ce0b 2020/11/06
Copyright 2000-2020 Willy Tarreau <willy@haproxy.org>

Build options :
  TARGET  = linux2628
  CPU     = generic
  CC      = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -Wno-null-dereference -Wno-unused-label -Wno-stringop-overflow
  OPTIONS = USE_LINUX_TPROXY=1 USE_CRYPT_H=1 USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_SYSTEMD=1 USE_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with OpenSSL version : OpenSSL 1.1.1k  FIPS 25 Mar 2021
Running on OpenSSL version : OpenSSL 1.1.1k  FIPS 25 Mar 2021
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with Lua version : Lua 5.3.4
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.42 2018-03-20
Running on PCRE version : 8.42 2018-03-20
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with zlib version : 1.2.11
Running on zlib version : 1.2.11
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available filters :
        [SPOE] spoe
        [COMP] compression
        [TRACE] trace

Now, you can start compiling:

make clean
make -j $(nproc) TARGET=linux-glibc USE_OPENSSL=1 USE_ZLIB=1 USE_LUA=1 USE_PCRE=1 USE_SYSTEMD=1

Note, USE_SYSTEMD=1 is needed for systemd notify support (specified with the Type keyword in systemd unit file. And to install to a different directory:

make PREFIX=/opt/haproxy-2.7.9 install

root@joetest:~/haproxy-2.7.9# /opt/haproxy-2.7.9/sbin/haproxy -vv
HAProxy version 2.7.9-7b77742 2023/06/07 - https://haproxy.org/
Status: stable branch - will stop receiving fixes around Q1 2024.
Known bugs: http://www.haproxy.org/bugs/bugs-2.7.9.html
Running on: Linux 5.4.17-2136.301.1.3.el8uek.x86_64 #2 SMP Mon Nov 29 21:03:24 PST 2021 x86_64
Build options :
  TARGET  = linux-glibc
  CPU     = generic
  CC      = cc
  CFLAGS  = -O2 -g -Wall -Wextra -Wundef -Wdeclaration-after-statement -Wfatal-errors -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference -fwrapv -Wno-address-of-packed-member -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers -Wno-cast-function-type -Wno-string-plus-int -Wno-atomic-alignment
  OPTIONS = USE_PCRE=1 USE_OPENSSL=1 USE_LUA=1 USE_ZLIB=1 USE_SYSTEMD=1
  DEBUG   = -DDEBUG_STRICT -DDEBUG_MEMORY_POOLS

Feature list : -51DEGREES +ACCEPT4 +BACKTRACE -CLOSEFROM +CPU_AFFINITY +CRYPT_H -DEVICEATLAS +DL -ENGINE +EPOLL -EVPORTS +GETADDRINFO -KQUEUE +LIBCRYPT +LINUX_SPLICE +LINUX_TPROXY +LUA -MEMORY_PROFILING +NETFILTER +NS -OBSOLETE_LINKER +OPENSSL -OPENSSL_WOLFSSL -OT +PCRE -PCRE2 -PCRE2_JIT -PCRE_JIT +POLL +PRCTL -PROCCTL -PROMEX -PTHREAD_EMULATION -QUIC +RT +SHM_OPEN -SLZ -STATIC_PCRE -STATIC_PCRE2 +SYSTEMD +TFO +THREAD +THREAD_DUMP +TPROXY -WURFL +ZLIB

Default settings :
  bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with multi-threading support (MAX_TGROUPS=16, MAX_THREADS=256, default=4).
Built with OpenSSL version : OpenSSL 1.1.1k  FIPS 25 Mar 2021
Running on OpenSSL version : OpenSSL 1.1.1k  FIPS 25 Mar 2021
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with Lua version : Lua 5.3.4
Built with network namespace support.
Running with a replaced memory allocator (e.g. via LD_PRELOAD).
Built with zlib version : 1.2.11
Running on zlib version : 1.2.11
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE version : 8.42 2018-03-20
Running on PCRE version : 8.42 2018-03-20
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Encrypted password support via crypt(3): yes
Built with gcc compiler version 8.5.0 20210514 (Red Hat 8.5.0-18.0.2)

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
         h2 : mode=HTTP  side=FE|BE  mux=H2    flags=HTX|HOL_RISK|NO_UPG
       fcgi : mode=HTTP  side=BE     mux=FCGI  flags=HTX|HOL_RISK|NO_UPG
  <default> : mode=HTTP  side=FE|BE  mux=H1    flags=HTX
         h1 : mode=HTTP  side=FE|BE  mux=H1    flags=HTX|NO_UPG
  <default> : mode=TCP   side=FE|BE  mux=PASS  flags=
       none : mode=TCP   side=FE|BE  mux=PASS  flags=NO_UPG

Available services : none

Available filters :
        [BWLIM] bwlim-in
        [BWLIM] bwlim-out
        [CACHE] cache
        [COMP] compression
        [FCGI] fcgi-app
        [SPOE] spoe
        [TRACE] trace

Then we can reuse the old version’s systemd unit file, just update the path:

root@joetest:~/haproxy-2.7.9# cat /usr/lib/systemd/system/haproxy.service
[Unit]
Description=HAProxy Load Balancer
After=network-online.target
Wants=network-online.target

[Service]
Environment="CONFIG=/etc/haproxy/haproxy.cfg" "PIDFILE=/run/haproxy.pid" "CFGDIR=/etc/haproxy/conf.d"
EnvironmentFile=/etc/sysconfig/haproxy
ExecStartPre=/usr/sbin/haproxy -f $CONFIG -f $CFGDIR -c -q $OPTIONS
ExecStart=/usr/sbin/haproxy -Ws -f $CONFIG -f $CFGDIR -p $PIDFILE $OPTIONS
ExecReload=/usr/sbin/haproxy -f $CONFIG -f $CFGDIR -c -q $OPTIONS
ExecReload=/bin/kill -USR2 $MAINPID
SuccessExitStatus=143
KillMode=mixed
Type=notify

[Install]
WantedBy=multi-user.target

Those variables can be specified in the envrionment file “/etc/sysconfig/haproxy” instead of putting them in the same file.

# Add extra options to the haproxy daemon here. This can be useful for
# specifying multiple configuration files with multiple -f options.
# See haproxy(1) for a complete list of options.

OPTIONS="-Ws"

# Specify an alternate configuration file. The default is:
CONFIG=/etc/haproxy/haproxy.cfg
CFGDIR=/etc/haproxy/conf.d

# File used to track process IDs. 
PIDFILE=/run/haproxy.pid

Now reload systemd and enable the service once you have a valid haproxy configuration (by editing haproxy configuration file):

systemctl daemon-reload
systemctl enable haproxy

Leave a comment