在 docker 容器中运行 protoc 命令

问题描述

我正在尝试将 protoc 命令运行到 docker 容器中。

我已尝试使用 gRPC image 但未找到 protoc 命令:

/bin/sh: 1: protoc: 未找到

所以我假设我必须使用 RUN 说明手动安装,但有更好的解决方案吗?安装了 protoc 的官方预编译映像?

另外,我尝试通过 Dockerfile 安装,但我再次遇到 protoc: not found

这是我的 Dockerfile

#I'm not using "FROM grpc/node" because that image can't unzip
FROM node:12 

...

# Download proto zip
ENV PROTOC_ZIP=protoc-3.14.0-linux-x86_32.zip
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/${PROTOC_ZIP}
RUN unzip -o ${PROTOC_ZIP} -d ./proto 
RUN chmod 755 -R ./proto/bin
ENV BASE=/usr/local
# copy into path
RUN cp ./proto/bin/protoc ${BASE}/bin
RUN cp -R ./proto/include/* ${BASE}/include

RUN protoc -I=...

我已经完成了 RUN echo $PATH 以确保文件夹在路径中并且没有问题:

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

还有 RUN ls -la /usr/local/bin 检查 protoc 文件是否在文件夹中并显示

-rwxr-xr-x 1 root root   4849692 Jan  2 11:16 protoc

所以文件在/bin文件夹中,文件夹在路径中。

我错过了什么吗?

另外,有没有一种简单的方法获取安装了 protoc 的图像?或者最好的选择是生成我自己的图像并从我的存储库中提取

提前致谢。

编辑:解决了下载 linux-x86_64 zip 文件而不是 x86_32 的问题。我下载了较低的架构要求,认为 x86_64 机器可以运行 x86_32 文件,但不能以其他方式运行。我不知道我是否遗漏了一些关于架构要求的东西(很可能)或者是一个错误

无论如何,如果它可以帮助某人找到解决方案,并且我已经添加了运行 protocprotoc-gen-grpc-web 所需的 Dockerfile 的答案。

解决方法

获得此类非默认工具的最简单方法是通过底层 Linux 发行版的包管理器安装它们。

首先,查看 Docker Hub page for the node image。 (对于像 node 这样的“库”图像,构造 URL https://hub.docker.com/_/node。)您会注意到有几个变体,名为“alpine”、“buster”或“stretch”;普通 node:12node:12-stretchnode:12.20.0-stretch 相同。 “alpine”镜像基于 Alpine Linux; "buster" 和 "stretch" 是 Debian GNU/Linux 的不同版本。

对于基于 Debian 的软件包,您可以在 https://packages.debian.org/ 上查找软件包(在页面底部的“搜索软件包内容”表单中输入 protoc)。这会将您带到 protobuf-compiler package。知道它包含 protoc 二进制文件,您可以使用以下命令将其安装在 Dockerfile 中:

FROM node:12 # Debian-based
RUN apt-get update \
 && DEBIAN_FRONTEND=noninteractive \
    apt-get install --no-install-recommends --assume-yes \
      protobuf-compiler
# The rest of your Dockerfile as above
COPY ...
RUN protoc ...

您通常必须在同一个 apt-get update 命令中运行 apt-get installRUN,以免后续重建从 Docker 构建缓存中获取旧版本的包缓存。如果我可以管理它,我通常只有一个 apt-get install 命令,为了可维护性,包按字母顺序排列在一行中。

如果映像是基于 Alpine 的,您可以在 https://pkgs.alpinelinux.org/contents 上进行类似的搜索以找到 protoc,并进行类似的安装:

FROM node:12-alpine
RUN apk add --no-cache protoc
# The rest of your Dockerfile as above
,

我终于解决了自己的问题。

问题在于 arch 版本:我使用的是 linux-x86_32.zip 但使用 linux-x86_64.zip

即使 @David Maze 的答案令人难以置信且如此完整,它并没有解决我的问题,因为使用 apt-get 安装版本 3.0.0 而我想要 3.14.0

所以,我用来在 docker 容器中运行 protoc 的 Dockerfile 是这样的:

FROM node:12

... 

# Download proto zip
ENV PROTOC_ZIP=protoc-3.14.0-linux-x86_64.zip
RUN curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v3.14.0/${PROTOC_ZIP}
RUN unzip -o ${PROTOC_ZIP} -d ./proto 
RUN chmod 755 -R ./proto/bin
ENV BASE=/usr
# Copy into path
RUN cp ./proto/bin/protoc ${BASE}/bin/
RUN cp -R ./proto/include/* ${BASE}/include/

# Download protoc-gen-grpc-web
ENV GRPC_WEB=protoc-gen-grpc-web-1.2.1-linux-x86_64
ENV GRPC_WEB_PATH=/usr/bin/protoc-gen-grpc-web
RUN curl -OL https://github.com/grpc/grpc-web/releases/download/1.2.1/${GRPC_WEB}
# Copy into path
RUN mv ${GRPC_WEB} ${GRPC_WEB_PATH}
RUN chmod +x ${GRPC_WEB_PATH}

RUN protoc -I=...

相关问答

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