pythondockeralpine-linuxdockerpy

standard_init_linux.go:211:exec user process caused "no such file or directory" with alpine linux and python


I have a directory which contains the docker file, a attack.py and a requirements.txt.

Using that, I created the following dockerfile:

FROM arm64v8/python:3.7-alpine

COPY qemu-arm-static /usr/bin

COPY ./ app-ids
WORKDIR /app-ids

RUN pip install --no-cache-dir -r requirements.txt

CMD["python","./attack.py"]

However, the pip install line throws: standard_init_linux.go:211:exec user process caused "no such file or directory"

I can't figure out why. Using commands like ls, pwd and so on in an attempt to debug this yields the same error.

Can anyone explain what exactly I am doing wrong?


Solution

  • I guess you are trying to build the docker image on a non-arm64v8 platform. I would assume that for the rest of the answer.

    The solution provided will be specific for Ubuntu distribution (host), but I guess it should be similar on other linux distribution.

    SOLUTION 1 [working on Ubuntu 18.04]

    From https://github.com/docker/for-linux/issues/56 we can see that there is bug currently in the packages for Debian (and thus Ubuntu?).

    sudo apt-get install qemu-user-static
    
    git clone https://github.com/computermouth/qemu-static-conf.git
    sudo mkdir -p /lib/binfmt.d
    sudo cp qemu-static-conf/*.conf /lib/binfmt.d/
    sudo systemctl restart systemd-binfmt.service
    

    This will remove the qemu-user-binfmt method from solution 2. However in that package the provided configuration files are not in the folder, and missconfigured, to be used by systemd-binfmt.

    Also, we get the configuration files from a git repository and place them in a folder where the systemd-binfmt looks into: /lib/binfmt.d/ (not /var/lib/binfmts/ as install by qemu-user-static)

    Then check the status:

    systemctl status systemd-binfmt
    

    And try to compile your docker again. It should work!

    SOLUTION 2 [not currently working on Ubuntu 18.04]

    It used to be a manually configuration process on previous, but now it is supported via a apt package:

    sudo apt-get install qemu-user-binfmt
    

    With that it will create the binfmt configuration for all platforms under /proc/sys/fs/binfmt_misc/qemu-*. And when your system detects that the executable is for arm, it will call qemu instead of trying to execute directly.

    Here is a link to a more detailed explanation: https://ownyourbits.com/2018/06/13/transparently-running-binaries-from-any-architecture-in-linux-with-qemu-and-binfmt_misc/ or https://ownyourbits.com/2018/06/27/running-and-building-arm-docker-containers-in-x86/

    To understand how it works, it is good to the following paragraph:

    The kernel recognizes the ARM ELF magic, and uses the interpreter /usr/bin/qemu-arm-static , which is the correct QEMU binary for the architecture. 0x7F 'ELF' in hexadecimal is 7f 45 4c 46, so we can see how the magic and the mask work together, considering the structure of the ELF header

    typedef struct {
        unsigned char e_ident[EI_NIDENT];   /* 0x7F 'ELF' four byte ELF magic for any architecture */
        uint16_t e_type;
        uint16_t e_machine;                 /* architecture code, 40=0x28 in the case of ARM */
        uint32_t e_version;
        ElfN_Addr e_entry;
        ElfN_Off e_phoff;
        ElfN_Off e_shoff;
        uint32_t e_flags;
        uint16_t e_ehsize;
        uint16_t e_phentsize;
        uint16_t e_phnum;
        uint16_t e_shentsize;
        uint16_t e_shnum;
        uint16_t e_shstrndx;
    } ElfN_Ehdr;
    

    Note that the binfmt configuration is shared by docker, therefore it will trying to get the /usr/bin/qemu-arm-static inside the container. And that is the reason you still need to copy the /usr/bin/qemu-arm-static.