如何在Alpine Linux中安装Go

56

我正在尝试在Alpine Docker镜像中安装Go。为此,我从这里下载了tar文件,并在我的alpine docker镜像中使用以下命令解压它:

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

将路径导出到go二进制文件,命令如下:

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

然而,当我输入go version时,显示sh: go: not found。我对alpine不太熟悉。有人知道我错过了什么吗?

复现步骤-

$ 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

echo $PATH 告诉你什么? - Jonathan Hall
/usr/local/go/bin # echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/go/bin - Yogesh Jilhawar
2
虽然这不是你直接问题的答案,但你可以使用其中一个官方的 Golang Alpine Docker 镜像。你也可以使用官方 Dockerfile 作为设置自己的指南。 - Jonathan Hall
1
你说得没错,但我的项目有一些特定的需求。 - Yogesh Jilhawar
在容器内执行Go二进制文件不需要安装上述的Go编译器...为了简化操作,建议您在其他地方(例如另一个容器)进行编译,然后将Go二进制文件作为卷挂载到容器中...这种分离方式可以更轻松地维护Go编译器和源代码的更新。 - Scott Stensland
显示剩余2条评论
9个回答

92

我只是使用多阶段构建将其复制过来,目前看起来还不错

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

13
+1 喜欢这个答案!我之前并没有意识到可以像这样组合两个 Docker 镜像。如果我想在一个容器中有两个主程序,我以前认为必须从一个镜像获取一个,并在 RUN 命令中安装另一个。太棒了! - Sean McCarthy
1
很棒的答案。查看当前的 golang Dockerfile ,你会看到最后几行与 Go 路径有关。如果你需要使用 Go 路径,则在 Dockerfile 的 COPY 之后加入以下内容: ENV GOPATH /go ENV PATH $GOPATH/bin:$PATH RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" - Davey
获取 bash: /usr/local/go/bin/go: 无法执行: 找不到所需的文件 - Sevy
Sevy,基础镜像可以选择其他的Linux发行版,尝试使用golang:1.13。 - serkan

44

以下的Dockerfile适合我使用。更简单且更抽象。

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"]

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


1
是的,这应该是更好的答案。 - John Siu

28
谢谢BMitch。
我编译了Go源代码,并在alpine镜像容器中执行了以下步骤。
echo "installing go version 1.10.3..." 
apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go 

# download go tar 
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/ 

# compile code
./make.bash 
export PATH="/usr/local/go/bin:$PATH"
export GOPATH=/opt/go/ 
export PATH=$PATH:$GOPATH/bin 
apk del .build-deps 
go version

2
当你运行 "apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go" 后,你可以运行 go version。为什么它们之间需要那些行呢? - biolinh
你也可以那样做。然而,我更关注安装特定版本的Go。 - Yogesh Jilhawar

16

使用Alpine时,您将拥有libmusl而不是glibc。 Alpine的libmusl并非一对一的替代品。链接到glibc的代码将显示未找到错误,实际上是来自动态链接器。您可以使用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)

有两个选项。首选选项是在Alpine上编译Go二进制文件,这也是Docker的Go镜像使用的方法。您可以在golang镜像的Dockerfile中看到这一点:https://github.com/docker-library/golang/blob/69f2d2a132565bf60afc91813801a3bdcc981526/1.10/alpine3.8/Dockerfile

另一个选择是在Alpine上安装glibc,但是一旦开始做这样的事情,我会质疑为什么要使用Alpine,以及Debian或CentOS是否更适合您作为基础镜像。Alpine有一个关于此的维基主题,并且有第三方已经创建了适用于Alpine的glibc软件包。(参见此处)


13

我发现在alpine linux上安装golang最好的方法是从源代码进行安装。这也是官方的alpine go docker镜像所遵循的方式。

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


7

如果基本要求是在alpine基础的docker镜像中安装特定的go版本,则可以参考官方golang dockerhub账户提供的镜像

docker pull golang:1.12-alpine
docker pull golang:1.11-alpine

2

Dockerfile

ARG GOLANG_VERSION=1.20.4
RUN wget https://go.dev/dl/go${GOLANG_VERSION}.linux-amd64.tar.gz && \
    rm -rf /usr/local/go && tar -C /usr/local -xzf go${GOLANG_VERSION}.linux-amd64.tar.gz && \
    rm go${GOLANG_VERSION}.linux-amd64.tar.gz
ENV PATH="${PATH}:/usr/local/go/bin"

非常直接,没有任何魔法。 - undefined

1

以防万一有人遇到和我一样的问题。

我按照@Yogesh Jilhawar的回答成功在Alpine3.15上安装了golang1.17.6。

当我运行命令apk add --no-cache --virtual .build-deps bash gcc musl-dev openssl go时,出现了以下错误:

ERROR: unable to select packages:
  go (no such packages):
    required by: world[go]

然后我尝试安装了"gcc-go",它成功安装。之后,我可以成功地从源代码构建Go语言。


-3

有Alpine软件包,内含最新版本的Go语言:

pkg --update add go


1
在 Alpine 上,默认情况下不存在名为 pkg 的二进制文件。 - shellscape

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接