首页 > 解决方案 > Golang 构建在 docker 和 requirements.txt 等效项中

问题描述

我知道Golang requirements.txt 等价物,但问题的上下文是相当不同的。

我正在尝试优化 docker 容器内的 golang 程序的构建。我的 dockerfile 看起来像这样:

FROM golang:1.12.5 as builder

WORKDIR $GOPATH/src/test-ldap/

COPY main.go .

RUN go get -d -v ./...
...

而我的main.go样子

package main

import (
  "log"
  "fmt"
  "gopkg.in/ldap.v3"
)

func main() {
...

当然,每次我对源代码进行更改时,都会更改 docker 层
COPY main.go .,因此go get需要重新运行该命令,并且即使该import块未更改,也无法从 docker build 缓存中重用该命令。

现在我当然可以输入类似

RUN go get -d -v log fmt gopkg.in/ldap.v3

并将其放在COPY陈述之前,但这违反了所谓的单一事实来源原则。如果我希望添加额外的导入,我将不得不在我的代码库中的两个不同位置更改相同的内容。

如何将我的导入要求存储在单独的文件中?在 Go 开发中这样做的惯用方法是什么?

标签: dockergo

解决方案


使用Go 模块。然后,像对待go.moda 一样对待生成的文件requirements.txt

FROM golang:1.12.5 as builder

# NOT in $GOPATH (or explicitly set GO111MODULES=on)
WORKDIR /usr/src/test-ldap/

COPY go.mod .
RUN go mod download  # alternatively: "go mod vendor" to build a vendor/ dir instead

COPY main.go .
# ...

推荐阅读