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?
By default all files created inside a container are stored on a writable container layer. This means that: The data doesn't persist when that container no longer exists, and it can be difficult to get the data out of the container if another process needs it.
Docker has an option to allow specific folders in a container to be mapped to the normal filesystem on the host. This allows us to have data in the container without making the data part of the Docker image, and without being bound to AUFS.
However, once you have created a container, it's not possible to keep making changes inside the Dockerfile every time you want to install something inside the container. Also, as soon as you exit the container, all the changes inside it are lost immediately.
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
You can use a volume instead of your local GOPATH
. the docker-compose.yml is like:
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:
The volume cache
is going to persist all the changes on the GOPATH for the container.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With