Run protoc command into docker container
Asked Answered
K

3

7

I'm trying to run protoc command into a docker container.

I've tried using the gRPC image but protoc command is not found:

/bin/sh: 1: protoc: not found

So I assume I have to install manually using RUN instructions, but is there a better solution? An official precompiled image with protoc installed?

Also, I've tried to install via Dockerfile but I'm getting again protoc: not found.

This is my 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=...

I've done RUN echo $PATH to ensure the folder is in path and is ok:

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

Also RUN ls -la /usr/local/bin to check protoc file is into the folder and it shows:

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

So the file is in /bin folder and the folder is in the path.

Have I missed something?

Also, is there a simple way to get the image with protoc installed? or the best option is generate my own image and pull from my repository?

Thanks in advance.

Edit: Solved downloading linux-x86_64 zip file instead of x86_32. I downloaded the lower architecture requirements thinking a x86_64 machine can run a x86_32 file but not in the other way. I don't know if I'm missing something about architecture requirements (It's probably) or is a bug.

Anyway in case it helps someone I found the solution and I've added an answer with the neccessary Dockerfile to run protoc and protoc-gen-grpc-web.

Kelp answered 2/1, 2021 at 11:29 Comment(0)
K
3

Finally I solved my own issue.

The problem was the arch version: I was using linux-x86_32.zip but works using linux-x86_64.zip

Even @David Maze answer is incredible and so complete, it didn't solve my problem because using apt-get install version 3.0.0 and I wanted 3.14.0.

So, the Dockerfile I have used to run protoc into a docker container is like this:

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=...
Kelp answered 3/1, 2021 at 21:18 Comment(0)
H
9

The easiest way to get non-default tools like this is to install them through the underlying Linux distribution's package manager.

First, look at the Docker Hub page for the node image. (For "library" images like node, construct the URL https://hub.docker.com/_/node.) You'll notice there that there are several variations named "alpine", "buster", or "stretch"; plain node:12 is the same as node:12-stretch and node:12.20.0-stretch. The "alpine" images are based on Alpine Linux; the "buster" and "stretch" ones are different versions of Debian GNU/Linux.

For Debian-based packages, you can then look up the package on https://packages.debian.org/ (type protoc into the "Search the contents of packages" form at the bottom of the page). That leads you to the protobuf-compiler package. Knowing that contains the protoc binary, you can install it in your Dockerfile with:

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 ...

You generally must run apt-get update and apt-get install in the same RUN command, lest a subsequent rebuild get an old version of the package cache from the Docker build cache. I generally have only a single apt-get install command if I can manage it, with the packages list alphabetically one to a line for maintainability.

If the image is Alpine-based, you can do a similar search on https://pkgs.alpinelinux.org/contents to find protoc, and similarly install it:

FROM node:12-alpine
RUN apk add --no-cache protoc
# The rest of your Dockerfile as above
Haviland answered 2/1, 2021 at 12:28 Comment(1)
Thank you so much for your explanation, but apt-get install version 3.0.0, not 3.14.0. I will test if 3.0.0 works fine too. Thanks again!Kelp
K
3

Finally I solved my own issue.

The problem was the arch version: I was using linux-x86_32.zip but works using linux-x86_64.zip

Even @David Maze answer is incredible and so complete, it didn't solve my problem because using apt-get install version 3.0.0 and I wanted 3.14.0.

So, the Dockerfile I have used to run protoc into a docker container is like this:

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=...
Kelp answered 3/1, 2021 at 21:18 Comment(0)
P
0

Because this is currently the highest ranked result on Google and the above instructions above won't work, if you want to use docker/dind for e.g. gitlab, this is the way how you can get the glibc-dependency working for protoc there:

#!/bin/bash

# install gcompat, because protoc needs a real glibc or compatible layer
apk add gcompat

# install a recent protoc (use a version that fits your needs)
export PB_REL="https://github.com/protocolbuffers/protobuf/releases"
curl -LO $PB_REL/download/v3.20.0/protoc-3.20.0-linux-x86_64.zip
unzip protoc-3.20.0-linux-x86_64.zip -d $HOME/.local
export PATH="$PATH:$HOME/.local/bin"

Privileged answered 8/4, 2022 at 10:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.