Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 752
m90 Avatar asked Aug 26 '18 12:08

m90


People also ask

Does data persist in docker container?

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.

Which allows containers to run with persistent volume?

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.

Are changes in docker container persistent?

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.


2 Answers

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
like image 50
m90 Avatar answered Oct 05 '22 18:10

m90


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.

like image 45
Motakjuq Avatar answered Oct 05 '22 18:10

Motakjuq