ChatGPT解决这个技术问题 Extra ChatGPT

Installed Go binary not found in path on Alpine Linux Docker

I've got a Go binary I'm trying to run on the Alpine Docker image.

This works fine for the Docker Go binary.

docker run -it alpine:3.3 sh
apk add --no-cache curl

DOCKER_BUCKET=get.docker.com
DOCKER_VERSION=1.9.1
curl -fSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-$DOCKER_VERSION" -o /usr/local/bin/docker
chmod +x /usr/local/bin/docker
docker help
Usage: docker [OPTIONS] COMMAND [arg...]
...

However, for the Go binary I want to install.

RACK_BUCKET=ec4a542dbf90c03b9f75-b342aba65414ad802720b41e8159cf45.ssl.cf5.rackcdn.com
RACK_VERSION=1.1.0-beta1
curl -fSL "https://${RACK_BUCKET}/${RACK_VERSION}/Linux/amd64/rack" -o /usr/local/bin/rack
chmod +x /usr/local/bin/rack

rack help
sh: rack: not found

/usr/local/bin/rack help
sh: /usr/local/bin/rack: not found

ls -al /usr/local/bin/
total 43375
drwxr-xr-x    2 root     root          1024 Jan 11 18:10 .
drwxr-xr-x    8 root     root          1024 Jan 11 18:09 ..
-rwxr-xr-x    1 root     root      30222575 Jan 11 18:09 docker
-rwxr-xr-x    1 root     root      14190576 Jan 11 18:10 rack

which rack
/usr/local/bin/rack

I thought it might have something to do with this answer but I don't get the same error when running ldd.

ldd /usr/local/bin/rack
    /lib64/ld-linux-x86-64.so.2 (0x7fdd15cd0000)
    libpthread.so.0 => /lib64/ld-linux-x86-64.so.2 (0x7fdd15cd0000)
    libc.so.6 => /lib64/ld-linux-x86-64.so.2 (0x7fdd15cd0000)

Any idea with this installed Go binary is not found in path on Alpine Linux Docker?

Did you run ldd on your host or within the alpine container? Did you check if the library files listed in the ldd output actually exist in the alpine image?
Ran ldd within the container. The library files listed in the ldd output do not exist in the Alpine image.
rack is linked to gnu libc, alipne uses musl libc.
Also when I run ldd /usr/local/bin/docker within the container, I get the output ldd: /usr/local/bin/docker: Not a valid dynamic program
ldd is for printing shared library dependencies, the docker binary is statically linked.

W
Wex
RUN mkdir /lib64 && ln -s /lib/libc.musl-x86_64.so.1 /lib64/ld-linux-x86-64.so.2

Since the musl and glibc so are compatible, you can make this symlink and it will fix the missing dependency.


The command fixed the issue for me. Could you elaborate why that is needed and if there is a way to avoid that when compiling the Go lib? thx
The installed Go version was compiled with glibc and on Alpine that is not installed by default. You can compile your Go with muslc, which is the default for Alpine, or do the symlink as above.
@GuerlandoOCs music was probably a typo for musl libc
Adding this line to the Dockerfile gives the following error # Error relocating ./my_go_binary: __fprintf_chk: symbol not found. Seems to be an incompatibility between the C libraries. Anyone else getting this error?
While this worked for me, it's still a workaround. At the end I chose to follow Kuldeep's answer and used CGO_ENABLED=0 go build. The resulting binary worked on Alpine.
K
Kuldeep Singh Pal

I compiled go binary in alpine with these options

GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o [name of binary]

It worked.


perhaps not terribly surprising, I found that when compiling for alpine docker on a mac machine, I needed the "GOOS=linux GOARCH=amd64" flags in addition to the "CGO_ENABLED=0" flag.
For anyone using Bazel, the above can be accomplished with the --features=static --features=pure flags.
If you want to do this with a package and "go get" you can directly do: CGO_ENABLED=0 go get -u YOUR_PACKAGE and obtain a binary that will work in alpine.
This is not a valid solution if you must keep CGO enabled.
k
knite

When building under Debian 9 (Stretch) / Go 1.10.2 and running under Alpine 3.7.0:

CGO_ENABLED=0 go build

Neither GOOS=linux nor GOARCH=amd6 was necessary.


This is not a valid solution if you must keep CGO enabled.
h
howie

You can install libc6-compat

RUN apk add --no-cache libc6-compat

I think that's the cleanest answer from a "consumer of the binary" point-of-view.
I did, but I still got errors not finding symbols Error loading shared library libstdc++.so.6: No such file or directory
j
johannzhaojohann

Depending on the nature of the program, you might want to compile your go program with static link options, such as the following:

-x -a -tags netgo -installsuffix netgo

Afterwards you do not need to worry about linking the correct libraries.


j
jotrocken

Alternatively, you can (meanwhile) use the golang:alpine image from Docker Hub to compile and run your code.

docker run -v ${YOUR_CODE_PATH}:/go/src/example -it golang:alpine sh
cd src/example
go build .
ldd example
    /lib/ld-musl-x86_64.so.1 (0x7f677fcf7000)
    libc.musl-x86_64.so.1 => /lib/ld-musl-x86_64.so.1 (0x7f677fcf7000)

Do you mean for compilation or as the runtime environment? Would using this image for compilation automatically compile a binary linked to musl? A bit more details in your answer would be great :)
Thanks for asking! I've updated the answer accordingly.
Is there any reason for using golang:alpine for running the application over just using the much smaller alpine image? golang:1.10-alpine is 376 MB while alpine:3.7 is 4.15 MB.
Maintenance effort I guess. It is still half the size of golang:latest. But you are right, if space matters more than maintainability, going with a plain alpine (pun intended) is the way to go.