Installed Go binary not found in path on Alpine Linux Docker
Asked Answered
A

7

69

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?

Auspice answered 11/1, 2016 at 19:44 Comment(6)
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?Wickiup
Ran ldd within the container. The library files listed in the ldd output do not exist in the Alpine image.Auspice
rack is linked to gnu libc, alipne uses musl libc.Freeboot
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 programAuspice
ldd is for printing shared library dependencies, the docker binary is statically linked.Freeboot
Thanks for the helpful comments. I've opened up the issue Statically link the rack binary.Auspice
S
135
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.

Snail answered 24/2, 2016 at 21:24 Comment(6)
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? thxTurboelectric
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.Snail
@GuerlandoOCs music was probably a typo for musl libcSilvery
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?Stylopodium
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.Sterigma
this answer is not correct as it is a workaround. the correct one is Kuldeep's one. you need to compile the program with CGO_ENABLED=0 optionKarakalpak
P
44

I compiled go binary in alpine with these options

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

It worked.

Perjured answered 13/12, 2016 at 18:35 Comment(4)
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.Longley
For anyone using Bazel, the above can be accomplished with the --features=static --features=pure flags.Falstaffian
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.Oxidation
This is not a valid solution if you must keep CGO enabled.Lankester
J
26

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.

Jolson answered 11/6, 2018 at 23:9 Comment(1)
This is not a valid solution if you must keep CGO enabled.Lankester
S
20

You can install libc6-compat

RUN apk add --no-cache libc6-compat
Sid answered 17/12, 2019 at 4:37 Comment(2)
I think that's the cleanest answer from a "consumer of the binary" point-of-view.Omnivore
I did, but I still got errors not finding symbols Error loading shared library libstdc++.so.6: No such file or directoryEvangelin
W
1

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.

Weingarten answered 15/5, 2017 at 20:40 Comment(0)
Y
0

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)
Yacketyyak answered 9/5, 2017 at 7:54 Comment(4)
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 :)Kellar
Thanks for asking! I've updated the answer accordingly.Yacketyyak
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.Kellar
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.Yacketyyak
O
0

So with libc6-compat i still got issues with not finding libresolv.so.2

RUN apk add --no-cache gcompat

and everything worked

See: https://github.com/golang/go/issues/59305 and its simple answer/resoludion https://github.com/golang/go/issues/59305#issuecomment-1541493132

Oversee answered 6/7, 2023 at 22:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.