在运行 Protocol Buffers 的基于 Alpine 的 Docker 容器上出现“protoc:未找到”

Kur*_*eek 8 linux protocol-buffers docker protoc

我正在尝试构建一个简单的容器,它从发布页面(https://github.com/protocolbuffers/protobuf/releases/tag/v3.13.0)下载 Protocol Buffers 二进制文件并将其添加到路径中。按照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
Run Code Online (Sandbox Code Playgroud)

问题是如果我使用构建它

docker build --tag docker-protoc .
Run Code Online (Sandbox Code Playgroud)

并在其中运行 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 # 
Run Code Online (Sandbox Code Playgroud)

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

/go # uname -m
x86_64
Run Code Online (Sandbox Code Playgroud)

知道为什么protoc不能在这个容器中执行吗?

Kur*_*eek 8

正如 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
Run Code Online (Sandbox Code Playgroud)

  • Alpine 在 apk `apk add protoc` 中也有协议,尽管版本不是最新的。 (3认同)
  • 虽然安装了这个 `protoc` alpine dep,但它不会附带 `descriptor.proto` 文件,它只会安装编译器。我需要“apk add protobuf-dev”来实际找到“/usr/include/google/protobuf”中的“descriptor.proto”文件,并最终构建我的原型模式。 (2认同)