I have an IRC bot that I build on my local machine, and I want to run it on my server. I'm running arch linux at home, which has the latest glibc (2.29 at the time of writing), but my server running debian ships with 2.28. I used to build the binary inside a docker container with the same versions as my server, but I'm currently on holiday, with a laptop with barely enough disk space for that.
Statically linked binary − a dead end
So at first, I tried to build a static binary that I could run on my server. To do so, I added a couple of things
ld-options: -static -pthread
ghc-options: -optl-static -optl-pthread -static
Then rebuild the whole thing
stack build --force-dirty, copy the binary somewhere convenient:
stack install --local-bin-path .
and check it's really statically linked:
ldd exec-name. You should get something like:
not a dynamic executable
But during compilation, I got a lot of warning like:
warning: Using 'endservent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
I could run the application just fine on my server with the static binary, until I tried to make an http request, and then, it crashed with a
Dynamically linked binary with custom glibc
So I ended up with this solution, which requires to build the correct version of glibc on the server. Follow the instructions
to build the library. Don't forget to run
make install at the end. This will create a directory
dist/lib (or just
lib) in the folder you ran
make build. Let's say
the library end up at
Then, following this stackoverflow answer, you need to specify where to find the required libraries when starting the executable
--library-path "/home/lambda/glibc-build/lib:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu/" \
libc, a haskell application needs a couple of other shared object, like
libgmp.so. These should be on your system already.
And that's it. Finally I can run this crucial IRC bot without having to muck around with docker.