如何在 Docker 容器中保留 go 1.11 模块?

How can I persist go 1.11 modules in a Docker container?

我正在将 Go 1.10 应用程序迁移到 Go 1.11。这还包括从 dep to mod 迁移以管理依赖项。

由于应用程序依赖于数据库,所以我使用 docker-compose 来设置本地开发环境。使用 Go 1.10,我只需将本地存储库(包括 vendor 文件夹)安装到容器 GOPATH:

中的正确位置
web:
  image: golang:1.10
  working_dir: /go/src/github.com/me/my-project
  volumes:
    - .:/go/src/github.com/me/my-project
  environment:
    - GOPATH=/go
    - PORT=9999
  command: go run cmd/my-project/main.go

自从 Go 1.11 开始 GOPATH(当使用模块时)我想我可以做到以下几点:

web:
  image: golang:1.11rc2
  working_dir: /app
  volumes:
    - .:/app
  environment:
    - PORT=9999
  command: go run cmd/my-project/main.go

这有效,但每次我 docker-compose up(或调用 Go 工具的任何其他命令)时,它都会解析并从头开始重新下载依赖关系树。当我 运行 容器外的命令(即在我的本地 OS 上)时,这不会发生(而只会发生一次)。

我如何改进设置,以便 Docker 容器保留由 go 工具下载的模块?

关于模块的 wiki 文章中没有提到这一点,但是通过阅读 go tool 上更新的文档,我发现在使用 Go 模块时,go 工具仍然会使用 GOPATH 存储可用的源,即 $GOPATH/pkg/mod.

这意味着对于我的本地开发设置,我可以 1. 在容器中定义 GOPATH 和 2. 将本地 $GOPATH/pkg/mod 挂载到容器的 GOPATH 中。

web:
  image: golang:1.11rc2
  working_dir: /app
  volumes:
    - .:/app
    - $GOPATH/pkg/mod:/go/pkg/mod
  environment:
    - GOPATH=/go
    - PORT=9999
  command: go run cmd/my-project/main.go

您可以使用卷代替本地 GOPATH。 docker-compose.yml 就像:

version: '3'

services:
  web:
    image: golang:1.11
    working_dir: /app
    volumes:
        - .:/app
        - cache:/go
    environment:
        - PORT=9999
    command: go run cmd/my-project/main.go

volumes:
  cache:

cache 将保留容器的 GOPATH 上的所有更改。