68

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?

Community
  • 1
  • 1
Everett Toews
  • 10,337
  • 10
  • 44
  • 45
  • 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? – helmbert Jan 11 '16 at 19:46
  • Ran `ldd` within the container. The library files listed in the `ldd` output do *not* exist in the Alpine image. – Everett Toews Jan 11 '16 at 19:51
  • 1
    rack is linked to gnu libc, alipne uses musl libc. – JimB Jan 11 '16 at 19:52
  • 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` – Everett Toews Jan 11 '16 at 19:52
  • `ldd` is for printing shared library dependencies, the `docker` binary is statically linked. – JimB Jan 11 '16 at 19:53
  • Thanks for the helpful comments. I've opened up the issue [Statically link the rack binary](https://github.com/rackspace/rack/issues/381). – Everett Toews Jan 11 '16 at 20:05

7 Answers7

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

Wex
  • 15,539
  • 10
  • 64
  • 107
sheldonk
  • 2,604
  • 3
  • 22
  • 32
  • 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? thx – Nils Jul 27 '16 at 08:23
  • 4
    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. – sheldonk Aug 05 '16 at 02:06
  • @GuerlandoOCs `music` was probably a typo for `musl libc` – atp Jan 16 '18 at 20:06
  • 2
    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? – thanos Mar 13 '18 at 17:04
  • 2
    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. – psmith May 30 '18 at 01:53
  • 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` option – Gianfranco Reppucci May 16 '19 at 17:19
41

I compiled go binary in alpine with these options

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

It worked.

  • 1
    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. – FuzzyAmi Jul 18 '17 at 08:06
  • 1
    For anyone using Bazel, the above can be accomplished with the `--features=static --features=pure` flags. – Ben Elgar Apr 16 '18 at 13:49
  • 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. – BBerastegui Nov 19 '19 at 16:24
  • This is not a valid solution if you must keep CGO enabled. – Lucat May 09 '22 at 16:13
25

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.

knite
  • 6,033
  • 6
  • 38
  • 54
19

You can install libc6-compat

RUN apk add --no-cache libc6-compat
howie
  • 2,587
  • 3
  • 27
  • 43
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.

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)
jotrocken
  • 2,263
  • 3
  • 27
  • 38
  • 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 :) – Hubro Mar 31 '18 at 22:17
  • Thanks for asking! I've updated the answer accordingly. – jotrocken Apr 05 '18 at 09:03
  • 1
    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. – Hubro Apr 05 '18 at 14:16
  • 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. – jotrocken Apr 05 '18 at 14:53
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

frooble
  • 155
  • 1
  • 5