简体   繁体   中英

Subprocess.Popen gives “No such file” when run inside Docker container

I am running a python application from inside a docker container. The application is a script that calls a set of executables sequentially using subprocess.

It script ran fine when I tested it as such on my Centos machine but fails with a "file not found" (presumably for the executable) when a subprocess calling an executable is invoked inside docker container

I have tried this by using both Python 2.7 and Centos7 as the base container but the problem persists.

The python code that gives the error is:

def __CallCommand(self, program, command):
        """ Allows execution of a simple command. """
        out = ""
        err = ""
        p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        out,err = p.communicate()

the error is: OSError: [Errno 2] No such file or directory

here is my dockerfile

FROM python:2.7-alpine


RUN mkdir -p /input
RUN mkdir -p /output
RUN mkdir -p /executables

COPY config.yml        .
COPY executables       /executables
COPY pipeline.py       .
COPY input             /input

ENTRYPOINT ["python", "pipeline.py", "-i", "/input/inputFile.txt", "-o", "output"]

It's not entirely clear from you summary how your solution works, but assuming that you iterate over the /executables and push these to your __CallCommand , it's possible that your executables won't work on Alpine if built (linked) on CentOS.

I'm able to build and run a repro of your code but using Alpine's (busybox) executables and not trying to copy binaries in. I then copied my local distro's echo , this fails (as expected)

You may wish to try running the executables you've copied on the container:

docker run --interactive --tty --entrypoint ash [[your-image]]`
/ # cd executables/
/executables # ls -l
total 32
-rw-r--r--    1 root     root             0 Apr  1 23:13 1
-rw-r--r--    1 root     root             0 Apr  1 23:13 2
-rwxr-xr-x    1 root     root         31464 Apr  1 23:38 echo
/executables # ldd echo
        /lib64/ld-linux-x86-64.so.2 (0x7f405d498000)
        libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7f405d498000)
Error relocating echo: __printf_chk: symbol not found
Error relocating echo: error: symbol not found
Error relocating echo: __fprintf_chk: symbol not found
/executables # ./echo Hello
ash: ./echo: not found

You should either:

  • use a non-Alpine FROM image
  • build binaries for Alpine
  • install glibc on Alpine

Additional detail

On Alpine (using its native|busybox) echo command:

ldd /bin/echo
        /lib/ld-musl-x86_64.so.1 (0x7ff4f8848000)
        libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7ff4f8848000)

You can see ' musl ` is used (Alpine uses this version of libc)

My local host has Debian and it uses GNU C Library ( glibc ):

ldd /bin/echo
        linux-vdso.so.1 (0x00007ffc88ff6000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6933af1000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f6934098000)

You can see libc.so links to gnu/libc

Thanks @DazWilkin! The interactive shell into the container helped immensely!

The first executable was a JRE file and my container did not have java (wonder what was I thinking :) running it without Java). Added Java and Python to a Centos container and I am able to run it now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM