How to install Go in alpine linux

59,697

Solution 1

Thanks BMitch.

I compiled the go source code and performed the below steps inside alpine image container.

echo "installing go version 1.10.3..." 
apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go 
wget -O go.tgz https://dl.google.com/go/go1.10.3.src.tar.gz 
tar -C /usr/local -xzf go.tgz 
cd /usr/local/go/src/ 
./make.bash 
export PATH="/usr/local/go/bin:$PATH"
export GOPATH=/opt/go/ 
export PATH=$PATH:$GOPATH/bin 
apk del .build-deps 
go version

Solution 2

I just copied it over using multi stage builds, seems to be ok so far

FROM XXX
 
COPY --from=golang:1.13-alpine /usr/local/go/ /usr/local/go/
 
ENV PATH="/usr/local/go/bin:${PATH}"

Solution 3

The following Dockerfile worked for me. Simpler and more abstract.

FROM alpine:latest

RUN apk add --no-cache git make musl-dev go

# Configure Go
ENV GOROOT /usr/lib/go
ENV GOPATH /go
ENV PATH /go/bin:$PATH

RUN mkdir -p ${GOPATH}/src ${GOPATH}/bin

# Install Glide
RUN go get -u github.com/Masterminds/glide/...

WORKDIR $GOPATH

CMD ["make"]

source: https://raw.githubusercontent.com/mickep76/alpine-golang/master/Dockerfile

Solution 4

With Alpine, you have libmusl instead of glibc. Alpine's libmusl is not a 1 for 1 replacement. Code linked against glibc will show a not found error which is actually from the dynamic linker. You can see what libraries are linked to the binary with ldd:

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

There are two options. The preferred option, and one used by docker's go images on Alpine, is to compile the go binaries on Alpine. You can see this in the Dockerfile for the golang image: https://github.com/docker-library/golang/blob/69f2d2a132565bf60afc91813801a3bdcc981526/1.10/alpine3.8/Dockerfile

The other option is to install glibc on Alpine, but once you start doing things like that, I'd question why use Alpine at all, and whether Debian or CentOS would be a more appropriate base image for you. Alpine has a wiki topic on this and there are third parties that have created glibc packages for alpine.

Solution 5

I found the best way to get golang up running in alpine linux is to install it from source. This is also way followed in the official alpine go docker images.

FROM alpine:3.12

ARG GOLANG_VERSION=1.14.3

#we need the go version installed from apk to bootstrap the custom version built from source
RUN apk update && apk add go gcc bash musl-dev openssl-dev ca-certificates && update-ca-certificates

RUN wget https://dl.google.com/go/go$GOLANG_VERSION.src.tar.gz && tar -C /usr/local -xzf go$GOLANG_VERSION.src.tar.gz

RUN cd /usr/local/go/src && ./make.bash

ENV PATH=$PATH:/usr/local/go/bin

RUN rm go$GOLANG_VERSION.src.tar.gz

#we delete the apk installed version to avoid conflict
RUN apk del go

RUN go version

Share:
59,697
Yogesh Jilhawar
Author by

Yogesh Jilhawar

Updated on July 09, 2022

Comments

  • Yogesh Jilhawar
    Yogesh Jilhawar almost 2 years

    I am trying to install Go inside an Alpine Docker image. For that I downloaded tar file from here inside my alpine docker image, untar it using following command:

    tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz

    exported PATH to have go binary as:

    export PATH=$PATH:/usr/local/go/bin

    However, when I say go version then it says that sh: go: not found. I am quite new to alpine. Does anyone know, what I am missing here?

    Steps to reproduce-

    $ docker run -it alpine sh
    $ wget https://dl.google.com/go/go1.10.3.linux-amd64.tar.gz
    $ tar -C /usr/local -xzf go1.10.3.linux-amd64.tar.gz
    $ export PATH=$PATH:/usr/local/go/bin
    $ go version
    
  • biolinh
    biolinh about 5 years
    when you run "apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go ", you can run go version after that. Why do you need those lines between them ?
  • Yogesh Jilhawar
    Yogesh Jilhawar about 5 years
    You can do that also. However, I focused more on installing specific version of go
  • John Siu
    John Siu over 4 years
    Yes, this should be the better answer.
  • Sean McCarthy
    Sean McCarthy over 3 years
    +1 Love this answer! I didn't realize one could combine two Docker images like that. Previously if I wanted two main programs in a container, I thought I had to get one FROM an image, and install the other one in a RUN command. Brilliant!
  • Davey
    Davey over 2 years
    Great answer. Looking at a current golang Dockerfile you can see the last few lines are related to the go path. If you need the go path then also include the following after the COPY in your Dockerfile ENV GOPATH /go ENV PATH $GOPATH/bin:$PATH RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
  • shellscape
    shellscape over 2 years
    pkg does not exist as a binary by default on Alpine