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.