Red
Red

Reputation: 1519

Docker doesn't see a binary in PATH inside container

I'm trying to build a Docker image to help automatize code generation from Google Protocol Buffers spec files.

My current Dockerfile:

FROM alpine:latest

WORKDIR /protobuf
VOLUME /dst

RUN apk update \
 && apk add --no-cache bash \
 && apk add --virtual .build-deps curl unzip \
 && curl -k -L https://github.com/google/protobuf/releases/download/v3.6.0/protoc-3.6.0-linux-x86_64.zip -o protoc.zip \
 && unzip protoc.zip \
 && rm protoc.zip \
 && chmod +x ./bin/protoc \
 && apk --purge del .build-deps

COPY . spec/
RUN chmod +x spec/entrypoint.sh

ENV SRC_DIR=/usr/src/protoc/spec DST_DIR=/dst PATH=/protobuf/bin:${PATH}
ENTRYPOINT [ "/bin/bash" ]

When I build and run it with TTY enabled, it runs without issue. However, shell inside the container is somehow unable to see the /protobuf/bin/protoc binary, even though it should be able to:

bash-4.4# echo $PATH
/protobuf/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
bash-4.4# ls -l /protobuf/bin
total 4444
-rwxr-xr-x    1 root     root       4548312 Jun 15 23:40 protoc
bash-4.4# protoc
bash: /protobuf/bin/protoc: No such file or directory

What can be the issue here?

Upvotes: 2

Views: 2189

Answers (1)

KamilCuk
KamilCuk

Reputation: 141030

protobuf is linked against glibc library and alpine uses musl (and older alpine used uclibc). They are not compatible. The error you are seeing comes from the linker not finding the libc standard library /lib64/ld-linux-x86-64.so.2. You can check that, by issuing ldd command:

$ ldd /bin/protoc 
    /lib64/ld-linux-x86-64.so.2 (0x7faa1a641000)
    libm.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7faa1a641000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7faa1a641000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7faa1a641000)
Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /bin/protoc)

The file exists and the PATH is ok.
To fix this you may install glibc on alpine (not recommended) or just move to a normal linux container.

@edit: My old answer was not true, bash nor sh does not source /etc/profile by default, only when supplied with -l option.

Upvotes: 3

Related Questions