Search code examples
dockergodocker-multi-stage-build

docker can't run a go output file that already exist


I'm building a multi-stage Dockerfile for my go project.

FROM golang:latest as builder

COPY ./go.mod /app/go.mod
COPY ./go.sum /app/go.sum

#exporting go1.11 module support variable
ENV GO111MODULE=on

WORKDIR /app/

#create vendor directory
RUN go mod download

COPY . /app/

RUN go mod vendor

#building source code
RUN go build -mod=vendor -o main -v ./src/


FROM alpine:latest
RUN apk --no-cache add ca-certificates
COPY --from=builder /app/main /app/main
WORKDIR /app/

ARG port="80"
ENV PORT=$port
EXPOSE $PORT

CMD ["./main"]

When I'm running the image, it throws error:

standard_init_linux.go:207: exec user process caused "no such file or directory"

I've verified that the 'main' file exist in /app/main. I also tried to give executable permission by adding

chmod +x /app/main

but still it doesn't work. What can possibly be wrong?


Solution

  • The "latest" version of the golang image is debian based, which uses libc. Alpine uses musl. If you do not compile with CGO_ENABLED=0, networking libraries will link to libc and the no such file or directory error point to a missing library. You can check these shared library links with ldd /app/main. A few solutions I can think of:

    • compile your program with CGO_ENABLED=0
    • switch your build image to FROM golang:alpine
    • change your second stage to be FROM debian