"protoc: not found" on an Alpine-based Docker container running Protocol Buffers
Asked Answered
K

4

9

I'm trying to build a simple container which downloads a Protocol Buffers binary from the release page (https://github.com/protocolbuffers/protobuf/releases/tag/v3.13.0) and adds it to the path. Following the Linux instructions at http://google.github.io/proto-lens/installing-protoc.html, I've attempted the following 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

The problem is that if I build it using

docker build --tag docker-protoc .

and run a shell in it, I get a protoc: not found error, even though the binary is in /usr/local/bin which is in the 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 # 

It also occurred to me that I might have downloaded a version of protoc that is not runnable on Alpine Linux, but the linux-x86_64 suffix seems to match the architecture of the container:

/go # uname -m
x86_64

Any idea why protoc can't be executed in this container?

Kepler answered 20/10, 2020 at 14:52 Comment(2)
Any idea because alpine uses musl, and the binary was compiled against glibcResuscitate
As @Resuscitate mentioned it is missing glibc, which could be solved by installing apk add gcompat wiki.alpinelinux.org/wiki/Running_glibc_programsDiscounter
K
8

As pointed out by KamilCuk, Alpine uses musl as its C standard library whereas the binary was compiled against glibc. My solution was to use the golang base image (which is based on Buster Linux) rather than 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
Kepler answered 20/10, 2020 at 15:2 Comment(2)
Alpine also has protoc in apk apk add protoc, although the version isn't quite the latest.Observant
Although installing this protoc alpine dep, it won't come with the descriptor.proto file, it will be installing only the compiler. I needed apk add protobuf-dev to actually locate the descriptor.proto file inside /usr/include/google/protobuf, and finally build my protos schemas.Ophite
B
5

Nowadays you will be fine with just a standard package:

FROM golang:alpine

RUN apk update && apk add --no-cache make protobuf-dev
Brownnose answered 9/2, 2022 at 10:43 Comment(0)
S
0

You can actually build protoc from its source according to the documentation. I am using the docker image, which is an alpine-based image and there is no Buster base image of it. Here is my 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

And then build the image:

docker build . -t protoc:0.0.1

After the build is over you can test it like this:

docker run --rm -it --entrypoint bash protoc:0.0.1
bash-5.1# protoc --version
libprotoc 3.19.4
Skinflint answered 18/2, 2022 at 11:35 Comment(0)
D
0

Actually, you can simply use:

FROM golang:1.20-alpine3.18
# install necessary packages
RUN apk update && \
    apk add --no-cache make protobuf-dev \
    && rm -rf /var/cache/apk/*

RUN go install google.golang.org/protobuf/cmd/protoc-gen-go@latest \
    && go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

RUN protoc --go_out=./ your_path/message.proto
Dori answered 6/9, 2024 at 12:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.