来自Docker的Golang编译缓存

时间:2017-10-25 12:10:14

标签: docker caching go build

我正在使用官方的golang alpine图像来编译我的源代码(我的主机是Mac),我注意到即使将整个$GOPATH安装在容器内部也不会使用来自先前版本的缓存数据。我检查它是否在$GOPATH/pkg目录中创建它,但它不会影响后续的构建速度。

但是,如果我重复使用同一个容器进行多次编译,它确实会使用某种缓存,你可以在这个实验中看到我做的结果:

使用不同的容器,每个构建中的时间大约为28-30秒:

$ rm -r $GOPATH/pkg/linux_amd64
$ time docker run -v$GOPATH:/go -e CGO_ENABLED=0 golang:1.9-alpine3.6 go build -i github.com/myrepo/mypackage
...
0.02s user 0.08s system 0% cpu 30.914 total

$ time docker run -v$GOPATH:/go -e CGO_ENABLED=0 golang:1.9-alpine3.6 go build -i github.com/myrepo/mypackage
...
0.02s user 0.07s system 0% cpu 28.128 total

重用相同的容器,后续构建要快得多:

$ rm -r $GOPATH/pkg/linux_amd64    
$ docker run -d -v$GOPATH:/go -e CGO_ENABLED=0 golang:1.9-alpine3.6 tail -f /dev/null
bb4c08867bf2a28ad87facf00fa9dcf2800ad480fe1e66eb4d8a4947a6efec1d

$ time docker exec bb4c08867bf2 go build -i github.com/myrepo/mypackage
...
0.02s user 0.05s system 0% cpu 27.028 total

$ time docker exec bb4c08867bf2 go build -i github.com/myrepo/mypackage
0.02s user 0.06s system 0% cpu 7.409 total

Go是否在$GOPATH之外的某个地方使用任何类型的缓存?

3 个答案:

答案 0 :(得分:1)

对于从Google搜索登陆到这里的任何人,我在reddit post上找到了有效的答案。

它基本上是说将/root/.cache/go-build映射到您的主机go build cache文件夹。

就我而言,我在Windows上,有一个需要与gcc进行交叉编译的项目,我不得不启动一个Linux容器来构建要部署到高山容器中的二进制文件,然后将其映射到数据量代替:

some-volume-name:/root/.cache/go-build

答案 1 :(得分:0)

当你在golang容器中构建时,它正在使用此容器中的$ GOPATH / pkg 目录。如果你然后启动另一个golang容器,它有一个空的$ GOPATH / pkg。但是,如果继续使用相同的容器(使用exec),则会重复使用$ GOPATH / pkg。

rm -r $GOPATH/pkg/linux_amd64只会删除本地计算机上的此目录。所以这没有效果。

重新使用同一容器的另一种可能方法是

  • 在第一次构建后提交容器,或
  • 将$ GOPATH / pkg作为主机或数据卷的卷挂载。

答案 2 :(得分:0)

使用-v标志打印正在编译的包。这可能是比花费时间更好的指标。

我能够通过将gopath作为音量安装来产生所需的结果(就像你所做的那样,所以它应该工作......)。请参阅下面的代码段。第一次它编译两个包,第二次只是主要的。

旁注:我采用这种方法的一个问题是音量目录将覆盖""覆盖" (即阴影)任何已经存在于该dir图像中的内容,如果您只使用基本golang alpine图像,那就没问题,因为/ go应该是空的。

pkm$ tree
.
└── src
    └── github.com
        ├── org1
        │   └── mine
        │       └── main.go
        └── org2
            └── somelib
                └── lib.go

6 directories, 2 files
pkm$ docker run --rm -v $GOPATH:/go golang:1.9-alpine go build -i -v github.com/org1/mine
github.com/org2/somelib
github.com/org1/mine
pkm$ tree
.
├── mine
├── pkg
│   └── linux_amd64
│       └── github.com
│           └── org2
│               └── somelib.a
└── src
    └── github.com
        ├── org1
        │   └── mine
        │       └── main.go
        └── org2
            └── somelib
                └── lib.go

10 directories, 4 files
pkm$ docker run --rm -v $GOPATH:/go golang:1.9-alpine go build -i -v github.com/org1/mine
github.com/org1/mine
pkm$ 
相关问题