我正在嘗試創建一個非常簡單的 docker 鏡像,它必須預先安裝 lua、luarocks 和其他一些可執行檔案,dockerfile 如下:
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
我嘗試使用 Alpine 和 Busybox 作為我的 Dockerfile 的基本映像,但是在運行這些可執行檔案時沒有成功,即使它們位于$PATH默認包含的目錄( /usr/local/bin) 中,每當我嘗試運行它們中的任何一個時,顯示以下錯誤:
$ lua
/bin/sh: lua: not found
我已經搜索并嘗試了我能想到的每一個可能的解決方案,但仍然沒有運氣
uj5u.com熱心網友回復:
特爾;博士:
該錯誤lua: not found是動態鏈接失敗的征兆,在嘗試在基于 musl-libc 的 Linux(例如 Alpine Linux 和基于 busybox 的映像)上運行大陸 Linux 二進制檔案時很常見。
要解決此問題,請切換到基于輕量級 glibc 的映像(例如 Debian Slim)或在 Alpine 容器上安裝 glibc。為 BusyBox 做這項作業是不切實際的。
完整說明:
一點背景。libc是標準 C 庫,為 Linux 程式提供 C 和 POSIX API,是 Linux 系統的固有部分。大多數 Linux 發行版都基于glibc,即 GNU C 庫。但是,Alpine Linux 和 BusyBox 映像都是基于musl標準 C 庫,通常與 glibc 不兼容。因此,在基于 glibc 的發行版(如 Ubuntu、Debian 或 Arch Linux)上構建的可執行檔案無法在 Alpine Linux 或 BusyBox 上開箱即用。
嘗試運行 glibc 可執行檔案時會出現鏈接錯誤。您可以通過將影像切換到alpine并運行來驗證這一點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
使用 Alpine Linux 的簡單而安全的解決方案是使用 Alpine 包管理器apk安裝兼容軟體。但是,Alpine 所需的軟體包可能不存在,因為特定的軟體包版本可能不可用。在這種情況下,您有兩個選擇:
- 使用基于 glibc 的 Docker 鏡像,例如 Debian slim 鏡像(例如
debian:buster-slim- 27MB 壓縮),而不是 Alpine/BusyBox - 在基于 musl 的映像上安裝 glibc,使其與 glibc 程式兼容,但也會顯著增加映像大小。
為什么不使用 BusyBox:
BusyBox 不適合這種定制。由于它甚至沒有包管理器,因此必須手動完成對它的所有更改和添加。這無疑是一個極其繁瑣和冗長的程序。Alpine 仍然是一個非常輕量級的映像,您可以相當簡單地在其中安裝 glibc。
使用 glibc 將影像更新為 Alpine:
首先,替換busybox為 Alpine,最好alpine:3.14是最新的 Alpine 版本(在兩個地方 - 第 1 行和第 37 行)。
其次,在COPY命令后添加以下幾行:
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
這將在 Alpine 容器上安裝 glibc。最后,運行luarocks。
作為參考,我已在pastebin上發布了 docker build 輸出。
uj5u.com熱心網友回復:
valiano 的回答很好地解釋了這個問題。但是,還有一個他沒有提到的解決方案,它不需要您使用 glibc:如果您從源代碼構建這些程式(作為構建程序的一部分在該容器中,或者在任何其他基于 musl 的環境中)而不是僅僅下載二進制檔案,那么它們就可以在您的容器中正常作業。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/321753.html
上一篇:命令findunix,linux
