尝试构建运行协议缓冲区的基于Alpine的Docker容器时出现“ / bin / ash:协议:未找到”

问题描述

我正在尝试构建一个简单的容器,该容器会从发行版(https://github.com/protocolbuffers/protobuf/releases/tag/v3.13.0)下载协议缓冲区二进制文件并将其添加到路径中。按照http://google.github.io/proto-lens/installing-protoc.html上的Linux说明,我尝试了以下Dockerfile

FROM golang:alpine

# Install protoc (cf. http://google.github.io/proto-lens/installing-protoc.html)
RUN apk add curl
ENV PROTOC_ZIP=protoc-3.13.0-linux-x86_64.zip
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.13.0/$PROTOC_ZIP \
    && unzip -o $PROTOC_ZIP -d /usr/local bin/protoc \
    && unzip -o $PROTOC_ZIP -d /usr/local 'include/*' \ 
    && rm -f $PROTOC_ZIP

问题是,如果我使用

构建它
docker build --tag docker-protoc .

并在其中运行shell,即使二进制文件位于protoc: not found中的/usr/local/bin中,我仍然遇到PATH错误

> docker run -it docker-protoc /bin/ash
/go # protoc
/bin/ash: protoc: not found
/go # ls /usr/local/bin
protoc
/go # echo $PATH
/go/bin:/usr/local/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
/go # 

我还想到我可能下载了protoc一个版本,该版本无法在Alpine Linux上运行,但是后缀linux-x86_64似乎与容器的体系结构匹配:

/go # uname -m
x86_64

您知道为什么无法在此容器中执行protoc吗?

解决方法

正如KamilCuk指出的那样,Alpine使用musl作为其C标准库,而二进制文件是针对glibc编译的。我的解决方案是使用golang基本映像(基于Buster Linux)而不是golang:alpine

FROM golang

# Install protoc (cf. http://google.github.io/proto-lens/installing-protoc.html)
ENV PROTOC_ZIP=protoc-3.13.0-linux-x86_64.zip
RUN apt-get update && apt-get install -y unzip
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.13.0/$PROTOC_ZIP \
    && unzip -o $PROTOC_ZIP -d /usr/local bin/protoc \
    && unzip -o $PROTOC_ZIP -d /usr/local 'include/*' \ 
    && rm -f $PROTOC_ZIP

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...