Docker - /bin/sh: file not found - bad ELF interpreter - how to add 32bit lib support to a docker image
UPDATE:
So the question becomes now:
- What would be the best way to achive the same result without repos or internet connection?
You could use various non-official 32-bit images available on DockerHub, search for debian32
, ubuntu32
, fedora32
, etc.
If you can't trust them, you can build such an image by yourself, and you can find instruction on DockerHub too, e.g.:
- on
f69m/ubuntu32
home page, there is a link to GitHub repo used to generate images; - on
hugodby/fedora32
home page, there is an example of commands used to build the image; - and so on.
Alternatively, you can prepare your own image based on some official image and add 32-bit packages to it.
Say, you can use a Dockerfile
like this:
FROM debian:wheezy
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get update
RUN apt-get install -y ia32-libs
...and use produced image as a base (with FROM
directive) for images you're building without internet access.
You can even create an automated build on DockerHub that will rebuild your image automatically when your Dockerfile
(posted, say, on GitHub) or mainline image (debian
in the example above) changes.
No matter how did you obtain an image with 32-bit support (used existing non-official image or built your own), you can then store it to a tar archive using docker save
command and then import using docker load
command.
CentOS 64 bit bad ELF interpreter
You're on a 64-bit system, and don't have 32-bit library support installed.
To install (baseline) support for 32-bit executables
(if you don't use sudo in your setup read note below)
Most desktop Linux systems in the Fedora/Red Hat family:
pkcon install glibc.i686
Possibly some desktop Debian/Ubuntu systems?:
pkcon install ia32-libs
Fedora or newer Red Hat, CentOS:
sudo dnf install glibc.i686
Older RHEL, CentOS:
sudo yum install glibc.i686
Even older RHEL, CentOS:
sudo yum install glibc.i386
Debian or Ubuntu:
sudo apt-get install ia32-libs
should grab you the (first, main) library you need.
Once you have that, you'll probably need support libs
Anyone needing to install glibc.i686
or glibc.i386
will probably run into other library dependencies, as well. To identify a package providing an arbitrary library, you can use
ldd /usr/bin/YOURAPPHERE
if you're not sure it's in /usr/bin
you can also fall back on
ldd $(which YOURAPPNAME)
The output will look like this:
linux-gate.so.1 => (0xf7760000)
libpthread.so.0 => /lib/libpthread.so.0 (0xf773e000)
libSM.so.6 => not found
Check for missing libraries (e.g. libSM.so.6
in the above output), and for each one you need to find the package that provides it.
Commands to find the package per distribution family
Fedora/Red Hat Enterprise/CentOS:
dnf provides /usr/lib/libSM.so.6
or, on older RHEL/CentOS:
yum provides /usr/lib/libSM.so.6
or, on Debian/Ubuntu:
first, install and download the database for apt-file
sudo apt-get install apt-file && apt-file update
then search with
apt-file find libSM.so.6
Note the prefix path /usr/lib
in the (usual) case; rarely, some libraries still live under /lib
for historical reasons … On typical 64-bit systems, 32-bit libraries live in /usr/lib
and 64-bit libraries live in /usr/lib64
.
(Debian/Ubuntu organise multi-architecture libraries differently.)
Installing packages for missing libraries
The above should give you a package name, e.g.:
libSM-1.2.0-2.fc15.i686 : X.Org X11 SM runtime library
Repo : fedora
Matched from:
Filename : /usr/lib/libSM.so.6
In this example the name of the package is libSM
and the name of the 32bit version of the package is libSM.i686
.
You can then install the package to grab the requisite library using pkcon
in a GUI, or sudo dnf/yum/apt-get
as appropriate…. E.g pkcon install libSM.i686
. If necessary you can specify the version fully. E.g sudo dnf install ibSM-1.2.0-2.fc15.i686
.
Some libraries will have an “epoch” designator before their name; this can be omitted (the curious can read the notes below).
Notes
Warning
Incidentially, the issue you are facing either implies that your RPM (resp. DPkg/DSelect) database is corrupted, or that the application you're trying to run wasn't installed through the package manager. If you're new to Linux, you probably want to avoid using software from sources other than your package manager, whenever possible...
If you don't use "sudo" in your set-up
Type
su -c
every time you see sudo
, eg,
su -c dnf install glibc.i686
About the epoch designator in library names
The “epoch” designator before the name is an artifact of the way that the underlying RPM libraries handle version numbers; e.g.
2:libpng-1.2.46-1.fc16.i686 : A library of functions for manipulating PNG image format files
Repo : fedora
Matched from:
Filename : /usr/lib/libpng.so.3
Here, the 2:
can be omitted; just pkcon install libpng.i686
or sudo dnf install libpng-1.2.46-1.fc16.i686
. (It vaguely implies something like: at some point, the version number of the libpng
package rolled backwards, and the “epoch” had to be incremented to make sure the newer version would be considered “newer” during updates. Or something similar happened. Twice.)
Updated to clarify and cover the various package manager options more fully (March, 2016)
Docker cookbook not finding Docker file
I believe you have a problem with the dockerfile
instead of Chef.
You should keep in mind that you are providing a relative path to the source of the files you want to copy.
In order to fix this, try using absolute paths for source and target paths, something like:
FROM centos
COPY /root/dockerimages/CentOS/wafflehouse.repo /etc/yum.repos.d/wafflehouse.repo
COPY /root/dockerimages/CentOS/wafflehouse-artifacts.repo /etc/yum.repos.d/wafflehouse-artifacts.repo
COPY /root/dockerimages/CentOS/wafflehouse-snapshot-artifacts.repo /etc/yum.repos.d/wafflehouse-snapshot-artifacts.repo
RUN yum install -y net-tools
CMD ["bash"]
Docker Alpine executable binary not found even if in PATH
On Alpine Linux, the not found
error is a typical symptom of dynamic link failure. It is indeed a rather confusing error by musl's ldd
linker.
Most of the world Linux software is linked against glibc, the GNU libc library (libc provides the standard C library and POSIX API). Most Linux distributions are based on glibc. OTOH, Alpine Linux is based on the musl libc library, which is a minimal implementation and strictly POSIX compliant. Executables built on glibc distributions depend on /lib/x86_64-linux-gnu/libc.so.6
, for example, which is not available on Alpine (unless, they are statically linked).
Except for this dependency, it's important to note that while musl attempts to maintain glibc compatibility to some extent, it is far from being fully compatible, and complex software that's built against glibc won't work with musl-libc, so simply symlinking /lib/ld-musl-x86_64.so.1
to the glibc path isn't likely going to work.
Generally, there are several ways for running glibc binaries on Alpine:
- Install one the glibc compatibility packages, libc6-compat or gcompat:
# apk add gcompat
apk add libc6-compat
Both packages provide a light weight glibc compatibility layer which may be suitable for running simple glibc applications.libc6-compat
implements glibc compatibility APIs and provides symlinks to glibc shared libraries such as libm.so
, libpthread.so
and libcrypt.so
. The gcompat
package is based on Adelie Linux gcompat project and does the same but provides a single library libgcompat.so
. Both libraries install loader stubs. Depdending on the application, one of them may work while the other won't, so it's good to try both.
- Install proper glibc on Alpine, for providing all glibc methods and functionalities. There are glibc builds available for Alpine, which should be installed in the following procedure (example):
# 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
Use statically linked executables. Static executables don't carry dynamic dependencies and could run on any Linux.
Alternatively, the software may be built from source on Alpine.
For LibreDWG, let's first verify the issue:
/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
You can see that dwg2dxf
depends on several glibc symbols.
Now, let's follow option 2 for installing 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 link
Voila:
/usr/local/bin # ./dwg2dxf
Usage: dwg2dxf [-v[N]] [--as rNNNN] [-m|--minimal] [-b|--binary] DWGFILES...
Bash: No such file or directory?
I bet you miss dynamic linker. Just do a
readelf --all ./wkhtmltopdf | grep interpreter
You should get an output like this:
[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
There are high chances that you system lacks the interpreter (/lib64/ld-linux-x86-64.so.2
in the example). In this case bash would yell No such file or directory
, just like when the binary itself is missing.
You can try to use a different linker. Sometime you can succeed. Just do a:
/path/to/the/linker /path/to/your/executable
This command:
find /lib* -name ld-linux\*
will help you find the linkers on your system. Or you can do the readelf
command on some command that does run. It will show you correct, working linker.
OR, since you are running Debian system, just do a
sudo apt-get install wkhtmltopdf
to install native version of the tool :)
Linux executable fails with File not found even though the file is there and in PATH
This:
$ file /usr/bin/wine
/usr/bin/wine: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32,
BuildID[sha1]=eaf6de433d8196e746c95d352e0258fe2b65ae24, stripped
Combined with this:
$ ldd /usr/bin/wine
/usr/bin/ldd: line 117: /usr/bin/wine: No such file or directory
Strongly suggests that the system does not have the /lib/ld-linux.so.2
ELF interpreter. That is, this 64-bit system does not have any 32-bit compatibility libraries installed. Thus, @user1334609's answer is essentially correct.
Related Topics
How to Change File Extension in Linux Shell Script
How to Add a Custom System Call on X86 Ubuntu Linux
Finding and Listing Duplicate Words in a Plain Text File
Releasing All Keys After Disabling The Keyboard in X11/Linux Using Xinput
How to Send Email from The Command Line
Why Does 'Ping' Not Timeout in Linux
Library Path Order for Alternate Glibc Dynamic Linker (Ld.So)
Shopify + Ubuntu 12.04Lts + Faraday Issue = Ok to Use Older Openssl
Where Do You Send The Kernel Console on an Embedded System
Monitor/Audit File Delete on Linux
How to Print on Stderr with Swift
Linux + Verify If File Is Text or Binary
I Need a Tcp Option (Ioctl) to Send Data Immediately
Write Something to Linux Hid Device
How to Compile Redis So That I Can Upload and Run It on Shared Hosting
How to Type "Cargo Run" Without Needing to Set The Ld_Library_Path Shell Variable