Hey,

Since 2016, a great Lua script has been used by many people deploying HAProxy instances that need to allow LetsEncrypt certificates generation: haproxy-acme-validation-plugin.

I’ve even written about how to respond to HTTP requests right from HAProxy: Making HAProxy respond 200 OK to health checks.

Many other scripts that extend HAProxy’s functionality have been made, but that’s not the point of this post.

If you ever need (or want) to test this script in a MacOS machine (or any other Lua script that enhances HAProxy), you’d need a special build of it: one that comes with Lua support.

Homebrew users have an easy time with this - since this commit, an extra option has been added: --lua, making the how installation a breeze:

# Install the `HAPROXY` brew formula with
# the extra `lua` option.
brew install haproxy \
        --with-lua

However, what if you want to install the very latest HAProxy version from source?

Installing HAProxy from source with Lua support

To install HAProxy from source on a Mac, we need to follow some steps:

  1. install HAProxy dependencies (you can discover these using brew info haproxy if you have brew);
  2. gather the source code from the official website;
  3. “untar” it; and
  4. compile the code using a set of flags that will allow us to build with the proper Lua support.

Aiming at Lua 5.3, it’s required that you first install it (you can use Homebrew for this):

brew install lua@5.3

To properly satisfy the first step though, it’s also important that you have the other dependencies as well:

# Discover what are the dependencies
# that have been set for HAProxy
brew info haproxy
==> Dependencies
Required: openssl ✔, pcre ✔
Optional: lua ✘

# Install the dependencies
brew install openssl
brew install pcre

Having that done, proceed with the download of the version you want (at this time, 1.9-dev0 is the very latest release):

# Set the version that we want to get the source
VERSION=1.9-dev0

# Grab the haproxy source from their website.
#
# Note that differently from the stable releases,
# the development version sits under `devel`.
#
# Make sure you properly modify the URL when you
# use the stable versions.
wget http://www.haproxy.org/download/1.9/src/devel/haproxy-$VERSION.tar.gz
tar xzf haproxy-$VERSION.tar.gz
cd haproxy-$VERSION

Being in the source directory of the HAProxy version, make sure that there’s no --export-dynamic property set in the LUA_LD_FLAGS line of the Makefile.

Such flag is not available in the MacOS linker, so, with it, your build will fail.

diff --git a/Makefile b/Makefile
index 26b55db..d02c858 100644
--- a/Makefile
+++ b/Makefile
@@ -629,7 +629,7 @@ check_lua_inc = $(shell if [ -d $(2)$(1) ]; then echo $(2)$(1); fi;)
 
 BUILD_OPTIONS   += $(call ignore_implicit,USE_LUA)
 OPTIONS_CFLAGS  += -DUSE_LUA $(if $(LUA_INC),-I$(LUA_INC))
-LUA_LD_FLAGS := -Wl,--export-dynamic $(if $(LUA_LIB),-L$(LUA_LIB))
+LUA_LD_FLAGS := -Wl $(if $(LUA_LIB),-L$(LUA_LIB))
 ifeq ($(LUA_LIB_NAME),)
 # Try to automatically detect the Lua library
 LUA_LIB_NAME := $(firstword $(foreach lib,lua5.3 lua53 lua,$(call check_lua_lib,$(lib),$(LUA_LD_FLAGS))))

With the Makefile fixed, proceed with the compilation:

# build the source code.
# for doing this you must at least have a recent C compiler

make -j6 \
TARGET=osx \
USE_KQUEUE=1 \
USE_POLL=1 \
USE_PCRE=1 \
USE_THREAD=1 \
USE_OPENSSL=1 \
USE_ZLIB=1 \
USE_LUA=1 \
LUA_LIB_NAME=lua \
LUA_LIB=/usr/local/lib/ \
LUA_INC=/usr/local/include \
SSL_LIB=/usr/local/opt/openssl/lib \
SSL_INC=/usr/local/opt/openssl/include \
ADDLIB=-lcrypto

# Check if everything was correctly installed.
./haproxy -vvvv
HA-Proxy version 1.9-dev0-b306650 2017/11/26
Copyright 2000-2017 Willy Tarreau <willy@haproxy.org>


..
  OPTIONS = USE_ZLIB=1 USE_POLL=1 USE_KQUEUE=1 USE_OPENSSL=1 USE_LUA=1 USE_PCRE=1
...
Built with Lua version : Lua 5.3.4
...

# link it to `/usr/local/bin/haproxy` (which is in my $PATH) so I
# can access it directly from `cli`
ln -s $(realpath haproxy) /usr/local/bin/haproxy

That’s it!

Now you should have the binary ready to be used.

If you want to know how to get TLS certificates with LetsEncrypt and HAProxy, make sure you check a blog post I wrote about the topic: Getting TLS certificates with Letsencrypt and HAProxy.

In case you have any questions, please let me know! I’m @cirowrc on Twitter and would love your feedback.

Also, make sure you subscribe to the mailing list if you like the topic!

Have a good one!

finis