【问题标题】:"protoc: not found" on an Alpine-based Docker container running Protocol Buffers“protoc: not found” 在运行 Protocol Buffers 的基于 Alpine 的 Docker 容器上
【发布时间】:2020-10-20 14:52:13
【问题描述】:

我正在尝试构建一个简单的容器,该容器从发布页面 (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

问题是,如果我使用它构建它

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 # 

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

/go # uname -m
x86_64

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

【问题讨论】:

标签: linux docker protocol-buffers protoc


【解决方案1】:

正如 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

【讨论】:

  • Alpine 在 apk apk add protoc 中也有 protoc,虽然版本不是最新的。
  • 虽然安装了这个protoc alpine dep,但它不会附带descriptor.proto 文件,它只会安装编译器。我需要apk add protobuf-dev/usr/include/google/protobuf 中实际找到descriptor.proto 文件,最后构建我的原型模式。
【解决方案2】:

现在你可能只需要:

FROM golang:1.17-alpine

RUN apk update && apk add --no-cache make protobuf-dev=3.18.1-r1

【讨论】:

    【解决方案3】:

    您实际上可以根据documentation 从其源代码构建协议。我正在使用docker image, which is an alpine-based image,并且没有它的 Buster 基础图像。这是我的 Dockerfile:

    FROM docker:20.10.12
    
    RUN apk update && apk add curl bash unzip build-base autoconf automake libtool make g++
    ENV PROTOBUF_VERSION 3.19.4
    ENV PROTOBUF_URL https://github.com/google/protobuf/releases/download/v"$PROTOBUF_VERSION"/protobuf-cpp-"$PROTOBUF_VERSION".zip
    RUN curl --silent -L -o protobuf.zip "$PROTOBUF_URL" && \
        unzip protobuf.zip && \
        cd protobuf-"$PROTOBUF_VERSION" && \
        ./configure && \
        make -j$(nproc) && \
        make install && \
        cd .. && rm protobuf.zip
    

    然后构建镜像:

    docker build . -t protoc:0.0.1
    

    构建完成后,您可以像这样测试它:

    docker run --rm -it --entrypoint bash protoc:0.0.1
    bash-5.1# protoc --version
    libprotoc 3.19.4
    

    【讨论】:

      猜你喜欢
      • 2021-09-14
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-11
      • 2018-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多