首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >即使在PATH中也找不到Docker高寒可执行二进制文件

即使在PATH中也找不到Docker高寒可执行二进制文件
EN

Stack Overflow用户
提问于 2021-04-06 05:18:18
回答 6查看 42.2K关注 0票数 38

我有一个高山运行容器,它包含usr/local/bin中的一些二进制文件。

当我ls usr/local/bin的内容时,我得到了以下输出:

代码语言:javascript
复制
/usr/local/bin # ls
dwg2SVG     dwg2dxf     dwgadd      dwgbmp      dwgfilter   dwggrep     dwglayers   dwgread     dwgrewrite  dwgwrite    dxf2dwg     dxfwrite

这正是我所期望的。但是,如果通过调用其中一个二进制文件来执行其中一个二进制文件,则从shell中得到一个not found错误:

代码语言:javascript
复制
/usr/local/bin # dwg2dxf
sh: dwgread: not found
/usr/local/bin # ./dwg2dxf
sh: ./dwgread: not found

我测试了我的$PATH,这似乎是正确的:

代码语言:javascript
复制
/usr/local/bin # echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

如何使这些二进制文件可调用或“可基础”?我是不是错过了我的Dockerfile构建中的什么?我想高山中的ldconfig命令可能出了问题,但我不确定。

编辑

正如在这里的一个答案中所建议的,我执行了file命令,下面是输出:

代码语言:javascript
复制
/usr/local/bin # file dwg2dxf
dwgread: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=7835d4a42651a5fb7bdfa2bd8a76e40096bacb07, with debug_info, not stripped

这些二进制文件来自LibreDWG官方存储库以及我的Dockerfile的第一部分。以下是完整的Dockerfile:

代码语言:javascript
复制
# podman/docker build -t libredwg .
############################
# STEP 1 build package from latest tar.xz
############################

FROM python:3.7.7-buster AS extracting
# libxml2-dev is broken so we need to compile it by our own
ARG LIBXML2VER=2.9.9
RUN apt-get update && \
    apt-get install -y --no-install-recommends autoconf libtool swig texinfo \
            build-essential gcc libxml2 python3-libxml2 libpcre2-dev libpcre2-32-0 curl \
            libperl-dev libxml2-dev && \
    mkdir libxmlInstall && cd libxmlInstall && \
    wget ftp://xmlsoft.org/libxml2/libxml2-$LIBXML2VER.tar.gz && \
    tar xf libxml2-$LIBXML2VER.tar.gz && \
    cd libxml2-$LIBXML2VER/ && \
    ./configure && \
    make && \
    make install && \
    cd /libxmlInstall && \
    rm -rf gg libxml2-$LIBXML2VER.tar.gz libxml2-$LIBXML2VER
WORKDIR /app
RUN tarxz=`curl --silent 'https://ftp.gnu.org/gnu/libredwg/?C=M;O=D' | grep '.tar.xz<' | \
         head -n1|sed -E 's/.*href="([^"]+)".*/\1/'`; \
    echo "latest release $tarxz"; \
    curl --silent --output "$tarxz" https://ftp.gnu.org/gnu/libredwg/$tarxz && \
    mkdir libredwg && \
    tar -C libredwg --xz --strip-components 1 -xf "$tarxz" && \
    rm "$tarxz" && \
    cd libredwg && \
    ./configure --disable-bindings --enable-release && \
    make -j `nproc` && \
    mkdir install && \
    make install DESTDIR="$PWD/install" && \
    make check DOCKER=1 DESTDIR="$PWD/install"

############################
# STEP 2 install into stable-slim
############################

# pull official base image
FROM osgeo/gdal:alpine-normal-latest

# set work directory
WORKDIR /usr/src/app



# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy requirements file
COPY ./requirements.txt /usr/src/app/requirements.txt

# install dependencies
RUN set -eux \
    && apk add --no-cache --virtual .build-deps build-base \
        py3-pip libressl-dev libffi-dev gcc musl-dev python3-dev postgresql-dev\
    && pip3 install --upgrade pip setuptools wheel \
    && pip3 install -r /usr/src/app/requirements.txt \
    && rm -rf /root/.cache/pip

# Install libredwg binaries
COPY --from=extracting /app/libredwg/install/usr/local/bin/* /usr/local/bin/
COPY --from=extracting /app/libredwg/install/usr/local/include/* /usr/local/include/
COPY --from=extracting /app/libredwg/install/usr/local/lib/* /usr/local/lib/
COPY --from=extracting /app/libredwg/install/usr/local/share/* /usr/local/share/
RUN ldconfig /usr/local/bin/
RUN ldconfig /usr/local/include/
RUN ldconfig /usr/local/lib/
RUN ldconfig /usr/local/share/

# copy project
COPY . /usr/src/app/
EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2021-04-06 18:40:07

在Alpine上,not found错误是动态链路故障的典型症状。这确实是musl的ldd链接器的一个相当令人困惑的错误。

世界上大多数Linux软件都是与滑翔、GNU库(libc提供标准C库和POSIX )链接的。大多数Linux发行版都基于glibc。OTOH,Alpine是基于musl libc库的,它是一个最小的实现,并且严格符合POSIX。例如,构建在glibc发行版上的可执行文件依赖于/lib/x86_64-linux-gnu/libc.so.6,这在高山上是不可用的(除非它们是静态链接的)。

除了这种依赖之外,重要的是要注意,尽管musl试图在某种程度上维护glibc兼容性,但它还远不是完全兼容的,而且构建在glibc上的复杂软件不能与musl一起工作,因此简单地将/lib/ld-musl-x86_64.so.1链接到glibc路径是不可能的。

通常,在高山上运行glibc二进制文件有几种方法:

  1. 安装一个glibc兼容性包,libc6 6-compat康帕特
代码语言:javascript
复制
# apk add gcompat
apk add libc6-compat

这两个包都提供了一个轻量级的glibc兼容性层,这可能适合于运行简单的glibc应用程序。libc6-compat实现了glibc兼容性API,并提供到libm.solibpthread.solibcrypt.so等glibc共享库的符号链接。gcompat包是基于gcompat项目的,它也是这样做的,但是提供了一个库libgcompat.so。这两个库都安装加载程序存根。在应用程序上,其中一个可以工作,而另一个不能工作,所以两者都可以尝试。

  1. 在高山上安装适当的glibc,以提供所有glibc方法和功能。对于阿尔卑斯山,可以使用glibc构建,这些构建应该安装在以下过程中(例如):
代码语言:javascript
复制
# Source: https://github.com/anapsix/docker-alpine-java

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
  1. 使用静态链接的可执行文件。静态可执行文件不带动态依赖项,可以在任何Linux上运行。
  2. 或者,软件可以从阿尔卑斯山的来源构建。

对于LibreDWG,让我们首先验证这个问题:

代码语言:javascript
复制
/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin
/usr/local/bin # ldd ./dwg2dxf
    /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
    libredwg.so.0 => /usr/local/lib/libredwg.so.0 (0x7fd3744db000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fd375538000)
Error relocating /usr/local/lib/libredwg.so.0: __strcat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __snprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __memcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __stpcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strcpy_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __printf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __fprintf_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __strncat_chk: symbol not found
Error relocating /usr/local/lib/libredwg.so.0: __sprintf_chk: symbol not found
Error relocating ./dwg2dxf: __snprintf_chk: symbol not found
Error relocating ./dwg2dxf: __printf_chk: symbol not found
Error relocating ./dwg2dxf: __fprintf_chk: symbol not found

您可以看到,dwg2dxf依赖于几个glibc符号。现在,让我们按照选项2安装glibc:

代码语言:javascript
复制
/usr/src/app # cd /usr/local/bin
/usr/local/bin # ls
dwg2SVG     dwg2dxf     dwgadd      dwgbmp      dwgfilter   dwggrep     dwglayers   dwgread     dwgrewrite  dwgwrite    dxf2dwg     dxfwrite
/usr/local/bin # ./dwg2dxf
/bin/sh: ./dwg2dxf: not found
/usr/local/bin # export GLIBC_REPO=https://github.com/sgerrand/alpine-pkg-glibc && \
> export GLIBC_VERSION=2.30-r0 && \
> 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
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.13/community/x86_64/APKINDEX.tar.gz
(1/1) Installing curl (7.74.0-r1)
Executing busybox-1.32.1-r3.trigger
OK: 629 MiB in 126 packages
(1/2) Installing glibc (2.30-r0)
(2/2) Installing glibc-bin (2.30-r0)
Executing glibc-bin-2.30-r0.trigger
/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link
OK: 640 MiB in 128 packages
removed '/tmp/glibc-2.30-r0.apk'
removed '/tmp/glibc-bin-2.30-r0.apk'
/usr/glibc-compat/sbin/ldconfig: /usr/glibc-compat/lib/ld-linux-x86-64.so.2 is not a symbolic link

/usr/glibc-compat/sbin/ldconfig: /usr/local/lib/libredwg.so.0 is not a symbolic link

瞧:

代码语言:javascript
复制
/usr/local/bin # ./dwg2dxf

Usage: dwg2dxf [-v[N]] [--as rNNNN] [-m|--minimal] [-b|--binary] DWGFILES...
票数 104
EN

Stack Overflow用户

发布于 2021-12-07 08:25:26

试试apk add gcompat (https://pkgs.alpinelinux.org/package/edge/community/x86/gcompat)。

gcompat同时提供了/lib64/ld-linux-x86-64.so.2/lib/ld-linux-x86-64.so.2 (https://pkgs.alpinelinux.org/contents?file=ld-linux-x86-64.so.2)。

票数 17
EN

Stack Overflow用户

发布于 2021-04-06 11:27:13

编辑:

有关完整的解决方案,请参阅@valiano的答复

下面是我在阅读@valiano的答复之前找到的一个解决办法

解决方案

通过切换到另一个基本映像(基于Ubuntu),我找到了一个解决办法--这里是新的工作 Dockerfile:

代码语言:javascript
复制
# podman/docker build -t libredwg .
############################
# STEP 1 build package from latest tar.xz
############################

FROM python:3.7.7-buster AS extracting
# libxml2-dev is broken so we need to compile it by our own
ARG LIBXML2VER=2.9.9
RUN apt-get update && \
    apt-get install -y --no-install-recommends autoconf libtool swig texinfo \
            build-essential gcc libxml2 python3-libxml2 libpcre2-dev libpcre2-32-0 curl \
            libperl-dev libxml2-dev && \
    mkdir libxmlInstall && cd libxmlInstall && \
    wget ftp://xmlsoft.org/libxml2/libxml2-$LIBXML2VER.tar.gz && \
    tar xf libxml2-$LIBXML2VER.tar.gz && \
    cd libxml2-$LIBXML2VER/ && \
    ./configure && \
    make && \
    make install && \
    cd /libxmlInstall && \
    rm -rf gg libxml2-$LIBXML2VER.tar.gz libxml2-$LIBXML2VER
WORKDIR /app
RUN tarxz=`curl --silent 'https://ftp.gnu.org/gnu/libredwg/?C=M;O=D' | grep '.tar.xz<' | \
         head -n1|sed -E 's/.*href="([^"]+)".*/\1/'`; \
    echo "latest release $tarxz"; \
    curl --silent --output "$tarxz" https://ftp.gnu.org/gnu/libredwg/$tarxz && \
    mkdir libredwg && \
    tar -C libredwg --xz --strip-components 1 -xf "$tarxz" && \
    rm "$tarxz" && \
    cd libredwg && \
    ./configure --disable-bindings --enable-release && \
    make -j `nproc` && \
    mkdir install && \
    make install DESTDIR="$PWD/install" && \
    make check DOCKER=1 DESTDIR="$PWD/install"

############################
# STEP 2 install into stable-slim
############################

# pull official base image
FROM osgeo/gdal:ubuntu-small-latest

# set work directory
WORKDIR /usr/src/app



# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# copy requirements file
COPY ./requirements.txt /usr/src/app/requirements.txt

# install dependencies
RUN set -eux \
    && apt-get update && apt-get install -y --no-install-recommends build-essential \
        libc6 python3-pip libffi-dev musl-dev gcc python3-dev postgresql-server-dev-all\
    && pip3 install --upgrade pip setuptools wheel \
    && pip3 install -r /usr/src/app/requirements.txt \
    && rm -rf /root/.cache/pip

# Install libredwg binaries
COPY --from=extracting /app/libredwg/install/usr/local/bin/* /usr/local/bin/
COPY --from=extracting /app/libredwg/install/usr/local/include/* /usr/local/include/
COPY --from=extracting /app/libredwg/install/usr/local/lib/* /usr/local/lib/
COPY --from=extracting /app/libredwg/install/usr/local/share/* /usr/local/share/
RUN ldconfig

# copy project
COPY . /usr/src/app/

基本上我只是改变了

代码语言:javascript
复制
FROM osgeo/gdal:alpine-normal-latest

代码语言:javascript
复制
FROM osgeo/gdal:ubuntu-small-latest

我还更新了依赖项安装(从apk add高寒PM切换到apt-get)

--对于我来说,这不是一个理想的解决方案,因为使用基于高寒的图像可以生成更轻量级的容器,但是它正在工作,所以我将其作为可能的解决方案发布。

@valiano的答复是,是最优解。如果你关心光的图片,请参考它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66963068

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档