Home > Back-end >  Cannot run executables with Alpine and Busybox docker images
Cannot run executables with Alpine and Busybox docker images

Time:10-18

I'm trying to create a very simple docker image, it must have lua, luarocks, and a few other executables pre-installed on it, dockerfile below:

FROM busybox AS builder

WORKDIR /usr/local/bin

# installs curl (reliable alternative to wget)
RUN wget -O curl https://github.com/moparisthebest/static-curl/releases/download/v7.79.1/curl-amd64 && \
    chmod  x curl

# installs luaformatter
RUN wget -O lua-format https://github.com/Koihik/vscode-lua-format/raw/master/bin/linux/lua-format && \
        chmod  x lua-format

# installs stylua
RUN wget -O stylua-0.11.0-linux.zip https://github.com/JohnnyMorganz/StyLua/releases/download/v0.11.0/stylua-0.11.0-linux.zip && \
        unzip stylua-0.11.0-linux.zip && \
        rm stylua-0.11.0-linux.zip && \
        chmod  x stylua

# installs selene
RUN wget -O selene-light-0.14.0-linux.zip https://github.com/Kampfkarren/selene/releases/download/0.14.0/selene-light-0.14.0-linux.zip && \
        unzip selene-light-0.14.0-linux.zip && \
        rm selene-light-0.14.0-linux.zip && \
        chmod  x selene

# installs lua (standalone binary)
RUN curl -k -o lua-5.4.2_Linux54_64_bin.tar.gz -L https://sourceforge.net/projects/luabinaries/files/5.4.2/Tools Executables/lua-5.4.2_Linux54_64_bin.tar.gz && \
    tar xvf lua-5.4.2_Linux54_64_bin.tar.gz && \
    mv lua54 lua && \
    rm -rf lua-5.4.2_Linux54_64_bin.tar.gz luac54

# installs luarocks (standalone binary)
RUN wget -O luarocks-3.7.0-linux-x86_64.zip https://luarocks.github.io/luarocks/releases/luarocks-3.7.0-linux-x86_64.zip && \
    unzip luarocks-3.7.0-linux-x86_64.zip && \
    mv luarocks-3.7.0-linux-x86_64/luarocks . && \
    rm -rf luarocks-3.7.0-linux-x86_64*

FROM busybox

COPY --from=builder /usr/local/bin /usr/local/bin

WORKDIR /ataraxis

RUN luarocks install luacheck

CMD stylua lua/ataraxis && \
    lua-format -i lua/ataraxis/*.lua && \
    luacheck --config .luacheckrc lua/ataraxis/*.lua && \
    selene lua/ataraxis

I tried using both Alpine and Busybox as base images for my Dockerfile, but had no success on running those executables, even though they are located on a directory that is included on $PATH by default (/usr/local/bin), whenever i try to run any of them, the following error is displayed:

$ lua
/bin/sh: lua: not found

I already searched and tried every single possible solution that i could think of, but still no luck

CodePudding user response:

TL;DR:

The error lua: not found is a symptom of a dynamic linking failure, and is common when trying to run mainland Linux binaries on musl-libc based Linux, such as Alpine Linux and the busybox based image.

To fix this, switch to a lightweight glibc based image (e.g. Debian Slim) or install glibc on the Alpine container. Making this work for BusyBox is unpractical.

Full Explanation:

A bit of background. libc, the standard C library, provides the C and POSIX APIs to Linux programs and is an intrinsic part of the Linux system. Most Linux distributions are based on glibc, the GNU C library. However, both Alpine Linux and BusyBox images are based on musl standard C library, which is generally incompatible with glibc. Consequently, executables that are built on glibc-based distros such as Ubuntu, Debian or Arch Linux, won't work out of the box on Alpine Linux or BusyBox.

The linking error is manifested when trying to run the glibc executable. You could verify this by switching the image to alpine and running ldd:

/ataraxis # ldd /usr/local/bin/luarocks 
    /lib64/ld-linux-x86-64.so.2 (0x7fbd14310000)
    libdl.so.2 => /lib64/ld-linux-x86-64.so.2 (0x7fbd14310000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7fbd14310000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fbd14310000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fbd14310000)
Error relocating /usr/local/bin/luarocks: __fprintf_chk: symbol not found
Error relocating /usr/local/bin/luarocks: makecontext: symbol not found
Error relocating /usr/local/bin/luarocks: setcontext: symbol not found
Error relocating /usr/local/bin/luarocks: __register_atfork: symbol not found
Error relocating /usr/local/bin/luarocks: __strdup: symbol not found
Error relocating /usr/local/bin/luarocks: __libc_alloca_cutoff: symbol not found
Error relocating /usr/local/bin/luarocks: __stpncpy: symbol not found
Error relocating /usr/local/bin/luarocks: __syslog_chk: symbol not found
Error relocating /usr/local/bin/luarocks: getcontext: symbol not found
Error relocating /usr/local/bin/luarocks: __open_2: symbol not found
Error relocating /usr/local/bin/luarocks: errno: symbol not found

The simple and safe solution for working with Alpine Linux is installing compatible software using the Alpine package manager, apk. However, the desired package may not exist for Alpine, for the specific package version may not be available. In this case, you have two options:

  • Use a glibc-based Docker image, such as Debian slim image (e.g. debian:buster-slim - 27MB compressed), instead of Alpine/BusyBox
  • Install glibc on the musl based image, making it compatible with glibc programs, but also increasing the image size considerably.

Why not BusyBox:

BusyBox is not suitable for this customization. Since it doesn't even have a package manager, all changes and additions to it must be be done manually. It is surely an extremely tedious and lengthy procedure. Alpine is still a very lightweight image, where you could install glibc fairly simply.

Updating the image to Alpine with glibc:

First, replace busybox with Alpine, preferably alpine:3.14 which is the latest Alpine release (in both places - line 1 and line 37).

Second, add the following lines after the COPY command:

ENV GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc
ENV GLIBC_VERSION=2.30-r0
RUN set -ex && \
    apk --update add libstdc   curl ca-certificates && \
    for pkg in glibc-${GLIBC_VERSION} glibc-bin-${GLIBC_VERSION}; \
        do curl -sSL ${GLIBC_REPO}/releases/download/${GLIBC_VERSION}/${pkg}.apk -o /tmp/${pkg}.apk; done && \
    apk add --allow-untrusted /tmp/*.apk && \
    rm -v /tmp/*.apk && \
    /usr/glibc-compat/sbin/ldconfig /lib /usr/glibc-compat/lib

This will install glibc on the Alpine container. Finally, run luarocks.
For reference, I have posted the docker build output on pastebin.

  • Related