Tengo un contenedor en ejecución alpino que contiene algunos archivos binarios en usr/local/bin
Cuando ls el contenido de usr/local/bin obtuve este resultado:
/usr/local/bin # ls dwg2SVG dwg2dxf dwgadd dwgbmp dwgfilter dwggrep dwglayers dwgread dwgrewrite dwgwrite dxf2dwg dxfwrite Que es lo que esperaba. Sin embargo, si ejecuto uno de estos binarios llamándolo, obtengo un error de not found del shell:
/usr/local/bin # dwg2dxf sh: dwgread: not found /usr/local/bin # ./dwg2dxf sh: ./dwgread: not found Probé mi $PATH que parece ser correcto:
/usr/local/bin # echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ¿Cómo puedo hacer que esos binarios sean invocables o "encontrables"? ¿Me perdí algo en mi compilación de Dockerfile? Supongo que hay algo con el comando ldconfig en alpine que salió mal, pero no estoy seguro.
EDITAR
Como se sugiere en una respuesta aquí, ejecuté el comando de file y aquí está el resultado:
/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 strippedEsos binarios son del repositorio oficial de LibreDWG , así como la primera parte de mi Dockerfile. Aquí está el Dockerfile completo:
# 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/Lo resolví así:
rm /usr/glibc-compat/lib/ld-linux-x86-64.so.2 ln -s /usr/glibc-compat/sbin/ldconfig /usr/glibc-compat/lib/ld-linux-x86-64.so.2 EDITAR: explicación: tanto /usr/glibc-compat/sbin/ldconfig como /usr/glibc-compat/lib/ld-linux-x86-64.so.2 eran archivos normales en el contenedor docker, así que probé uno de ellos .
Primero /usr/glibc-compat/sbin/ldconfig y lo convertí en un enlace simbólico. Pero tengo un error, no recuerdo cuál. A continuación, traté de eliminar ld-linux-x86-64.so.2 y convertirlo en un enlace simbólico. Eso funciono.
Ahora podemos usar docker compose para reemplazar docker-compose
Para Alpine Linux, instale por
apk add docker-cli-compose Si aún prefiere docker-compose , puede guardar un archivo en /usr/local/bin/docker-compose con a+x:
#!/bin/sh docker compose $@ Luego, aún puede ejecutar los scripts antiguos que usan docker-compose .
Intente apk add gcompat (https://pkgs.alpinelinux.org/package/edge/community/x86/gcompat ).
gcompat proporciona /lib64/ld-linux-x86-64.so.2 y /lib/ld-linux-x86-64.so.2 (https://pkgs.alpinelinux.org/contents?file=ld-linux -x86-64.so.2 ).
Es posible que no esté en un formato binario que pueda usar en el sistema en cuestión. Verifique su arquitectura y el formato de archivo (por ejemplo, usando el comando de file ).
Editar: ¿Existe /lib64/ld-linux-x86-64.so.2 ? ¿Puedes ejecutarlo?
Edición adicional: la idea general aquí es que un binario vinculado dinámicamente se puede considerar como un script con un intérprete. Consulte este artículo de LWN para obtener detalles adicionales para comprender lo que puede estar sucediendo aquí. Si sus binarios son para la plataforma incorrecta, necesitará nuevos binarios o deberá ejecutarlos en la plataforma adecuada.
Otra cosa que puede verificar es si la salida del file para este binario difiere de la salida del file para los binarios que funcionan correctamente (por ejemplo /bin/ls ).
EDITAR:
Para obtener una solución completa, consulte @valiano'response .
Aquí hay solo una solución que encontré antes de leer la respuesta de @valiano
SOLUCIÓN ALTERNA
Encontré una solución al cambiar a otra imagen base (basada en Ubuntu) Aquí está el nuevo Dockerfile en funcionamiento :
# 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/Básicamente, acabo de cambiar el
FROM osgeo/gdal:alpine-normal-latestPara
FROM osgeo/gdal:ubuntu-small-latest También actualicé la instalación de dependencias (cambiando de apk add alpine PM a apt-get )
Esta no es una solución ideal para mí, ya que el uso de una imagen alpina genera un contenedor más liviano, pero funciona, así que lo publico como una posible solución.
La respuesta de @valiano es la solución óptima . Consúltelo si le interesan las imágenes ligeras.
En Alpine Linux, el error not found es un síntoma típico de falla de enlace dinámico. De hecho, es un error bastante confuso por parte del enlazador ldd de ldd .
La mayor parte del software Linux del mundo está vinculado a glibc , la biblioteca libc de GNU (libc proporciona la biblioteca C estándar y la API POSIX). La mayoría de las distribuciones de Linux se basan en glibc. OTOH, Alpine Linux se basa en la biblioteca musl libc, que es una implementación mínima y cumple estrictamente con POSIX. Los ejecutables creados en distribuciones glibc dependen de /lib/x86_64-linux-gnu/libc.so.6 , por ejemplo, que no está disponible en Alpine (a menos que estén vinculados estáticamente).
Excepto por esta dependencia, es importante tener en cuenta que, si bien musl intenta mantener la compatibilidad con glibc hasta cierto punto, está lejos de ser totalmente compatible, y el software complejo creado contra glibc no funcionará con musl-libc, por lo que simplemente vincular /lib/ld-musl-x86_64.so.1 a la ruta glibc probablemente no funcione.
En general, hay varias formas de ejecutar binarios glibc en Alpine:
# apk add gcompat apk add libc6-compat Ambos paquetes proporcionan una capa ligera de compatibilidad con glibc que puede ser adecuada para ejecutar aplicaciones glibc simples. libc6-compat implementa API de compatibilidad con glibc y proporciona enlaces simbólicos a bibliotecas compartidas de glibc como libm.so , libpthread.so y libcrypt.so . El paquete gcompat se basa en el proyecto gcompat de Adelie Linux y hace lo mismo, pero proporciona una sola biblioteca libgcompat.so . Ambas bibliotecas instalan stubs de cargador. Dependiendo de la aplicación, uno de ellos puede funcionar y el otro no, por lo que es bueno probar ambos.
# 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/libUtilice ejecutables vinculados estáticamente. Los ejecutables estáticos no tienen dependencias dinámicas y podrían ejecutarse en cualquier Linux.
Alternativamente, el software puede compilarse a partir de la fuente en Alpine.
Para LibreDWG, primero verifiquemos el problema:
/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 Puede ver que dwg2dxf depende de varios símbolos glibc. Ahora, sigamos la opción 2 para instalar glibc:
/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 linkVoilá:
/usr/local/bin # ./dwg2dxf Usage: dwg2dxf [-v[N]] [--as rNNNN] [-m|--minimal] [-b|--binary] DWGFILES...