Search code examples
dockergodocker-composevgogo-modules

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


I am migrating a Go 1.10 app to Go 1.11. This also includes migrating from dep to mod for managing dependencies.

As the application depends on a database, I am using a docker-compose to set up the local development environment. With Go 1.10 I simply mounted the local repository (including the vendor folder) into the correct location in the container's 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

Since Go 1.11 ditches GOPATH (when using modules that is) I thought I could just do the following:

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

This works, but every time I docker-compose up (or any other command that calls through to the Go tool) it will resolve and re-download the dependency tree from scratch. This does not happen (rather only once) when I run the command outside of the container (i.e. on my local OS).

How can I improve the setup so that the Docker container persists the modules being downloaded by the go tool?


Solution

  • This is not mentioned in the wiki article on modules, but from reading the updated docs on the go tool, I found out that when using Go modules, the go tool will still use GOPATH to store the available sources, namely $GOPATH/pkg/mod.

    This means that for my local dev setup, I can 1. define the GOPATH in the container and 2. mount the local $GOPATH/pkg/mod into the container's 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