Today I needed to install an old mysql ruby gem. I’m building it all in a lightweight Alpine Docker image, but I hit the problem that newer Alpine has settled on mariadb, and I was getting all sorts of issues with binding against the correct shared libraries.

I knew that I could use mysqlclient v5.6.51, so I decided to try and ditch the Alpine apks mysql-client and mariadb-dev and build from the old mysql source instead.

mysql builds with cmake so I needed a few extra packages: apk add bash build-base autoconf openssl openssl-dev ncurses ncurses-dev wget cmake.

Then you cd into the the unpacked mysql source directory and call cmake -DWITHOUT_SERVER:BOOL=ON && make && make install.

When I’d initially built and installed it, everything looked good, until the ruby gem was called:

Error loading shared library libmysqlclient.so.18: No such file or directory (needed by /lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.so)

Oh no. I could see that I did have the shared library - it was in /usr/local/mysql/lib, because the mysql install defaults to a /user/local/mysql install prefix.

You can tell Alpine where else to look for shared library code by creating an /etc/ld-musl-$(ARCH).path file (i.e. /etc/ld-musl-x86_64.path or /etc/ld-musl-aarch64.path) which I discovered thanks to this Stackoverflow comment. It defaults to /lib:/usr/local/lib:/usr/lib if it’s not present, so I created /etc/ld-musl-aarch64.path with these paths: /lib:/usr/local/lib:/usr/lib:/usr/local/mysql/lib and then when I called ldd /lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.so it could find the shared libraries. This seemed OK, but a little messy.

By changing the options you pass to cmake, you can change where the shared libraries are installed to:

cmake -DWITHOUT_SERVER:BOOL=ON -DCMAKE_INSTALL_PREFIX=/ && \
make && make install

Now the libmysqlclient files are all to be found in the /lib folder and you don’t need the /etc/ld-musl-$(ARCH).path file.

Here’s the final Dockerfile:

FROM alpine:latest

RUN apk add --no-cache bash build-base autoconf openssl openssl-dev ncurses ncurses-dev wget cmake && \
    wget -O /tmp/mysql-5.6.51.tar.gz https://cdn.mysql.com/archives/mysql-5.6/mysql-5.6.51.tar.gz && \
    cd /tmp && tar -zxf /tmp/mysql-5.6.51.tar.gz && \
    cd /tmp/mysql-5.6.51 && cmake -DWITHOUT_SERVER:BOOL=ON -DCMAKE_INSTALL_PREFIX=/ && \
    make && make install && \
    rm -rf /tmp/mysql* && rm -rf /var/cache/apk/*