Introduction
Since I always forget to write down all the dependencies and make options, here are my scribbly notes on how to compile HAProxy on Fedora 29/Fedora 30.
Where to get the source
The GitHub URL is a mirror of the main repository and doesn't contain the other branches. It's handy and works fine if you're on the master branch: https://github.com/haproxy/haproxy
Other locations to get the source include:
https://www.haproxy.org/download/
http://git.haproxy.org/
Dependencies
dnf install pcre2 pcre2-devel lua lua-devel openssl-devel \
systemd-devel jemalloc jemalloc-devel git gcc zlib-devel make perl
Compiling
HAProxy versions before 2.0:
CFLAGS="-O2 -g -fno-strict-aliasing" ADDLIB="-ljemalloc -lpthread" \
make -j4 -pipe TARGET=linux2628 USE_LINUX_TPROXY=1 USE_TFO=1 USE_LIBSLZ=1 \
USE_REGPARM=1 USE_PCRE2_STATIC=1 USE_PCRE2_JIT=1 USE_OPENSSL=1 \
USE_SYSTEMD=1 USE_NS=1 USE_LUA=1
HAProxy 2.0 changes the build targets and also introduces the prometheus exporter, which changes the syntax a bit:
EXTRA_OBJS="contrib/prometheus-exporter/service-prometheus.o" \
CFLAGS="-O2 -g -fno-strict-aliasing" ADDLIB="-ljemalloc -lpthread" \
make -j4 -pipe TARGET=linux-glibc USE_LINUX_TPROXY=1 USE_TFO=1 \
USE_LIBSLZ=1 USE_REGPARM=1 USE_PCRE2_STATIC=1 USE_PCRE2_JIT=1 \
USE_OPENSSL=1 USE_SYSTEMD=1 USE_NS=1 USE_LUA=1
Adjust the -j value to match the number of CPU cores on your system / how many you want to use for compiling. For the meaning of the values, see the INSTALL file located under the root of the haproxy git repository.
Installation
make install
Unless you configure a different prefix, this will install haproxy to /usr/local/sbin/haproxy. For the init scripts, and SELinux module support see the contrib folder. Personally I find both to be overkill, as Fedora provides a haproxy policy that is suitable if you follow the targeted policy in /etc/selinux (just install the regular haproxy package), and I use a simplified systemd service file.
My prefered systemd script
The following init script supports multiple haproxy instances running on a single server. It takes advantage of the systemd @ syntax, where e.g. systemctl start haproxy@web starts haproxy with the /etc/haproxy/configs-enabled/web.cfg configguration file. Also, the configs-available / configs-enabled syntax takes inspiration from the debian apache/nginx folder organization, where configurations are symlinked to help distinguish between active and archived configuration files.
[Unit]
Description=HAProxy Load Balancer
After=network.target
[Service]
Environment="CONFIG=/etc/haproxy/configs-enabled/%i.cfg" "PIDFILE=/run/haproxy-%i.pid"
ExecStartPre=/usr/local/sbin/haproxy -f $CONFIG -c -q
ExecStart=/usr/local/sbin/haproxy -Ws -f $CONFIG -p $PIDFILE
ExecReload=/usr/local/sbin/haproxy -f $CONFIG -c -q
ExecReload=/bin/kill -USR2 $MAINPID
KillMode=mixed
Type=notify
[Install]
WantedBy=multi-user.target
SELinux considerations
Unless nis_enabled or haproxy_connect_any are set, HAProxy won't be allowed to connect to backends servers listening on specific ports. To avoid this issue, it is a good idea, to set either one of these SELinux booleans to on:
setsebool -P haproxy_connect_any on
or
setsebool -P nis_enabled on
Pitfalls
The options might not be ideal, this is more of a "Christmas packet" type-build (for CI/CD, to test out HAProxy will build with most options turned on)). For production use, you will want to tweak this further. Don't stick this in a Dockerfile and expect it to work flawlessly!