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:
dnf install pcre2 pcre2-devel lua lua-devel openssl-devel \ systemd-devel jemalloc jemalloc-devel git gcc zlib-devel make perl
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.
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
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
setsebool -P nis_enabled on
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!