web-dev-qa-db-fra.com

Comment télécharger toutes les dépendances avec vgo et un go.mod donné?

Je travaille sur un projet go, en utilisant vgo, avec un fichier Docker, et j'aimerais que docker mette en cache les dépendances du projet, de sorte qu'il ait deux propriétés:

  1. Si le fichier go.mod change, les dépendances seront à nouveau téléchargées.
  2. Si je modifie un fichier dans le package sans modifier go.mod, les dépendances ne seront pas téléchargées à nouveau.

En ce moment, je fais:

...
RUN go get -u golang.org/x/vgo
COPY . /go/src/whatever
RUN vgo install
...

Mais si vous modifiez un fichier go, le fichier docker devra être reconstruit à partir de la couche COPY.

Ce que j'aimerais, en bref, c'est faire:

...
RUN go get -u golang.org/x/vgo
COPY go.mod /go/src/whatever
RUN vgo install_dependencies
COPY . /go/src/whatever
RUN vgo install
...

Ainsi, si je change de go.mod, toutes les dépendances seront téléchargées et reconstruites, mais sinon, nous pouvons continuer à construire le binaire.

Je peux voir plusieurs façons d'avoir un comportement comme celui-ci, mais elles ont toutes des inconvénients:

  1. Je pourrais copier $GOPATH/src/mod dans le conteneur de menu fixe, mais il y aura beaucoup de fichiers dont je n'ai pas besoin
  2. Je pourrais vgo mod -vendor avant de construire le conteneur Docker et copier le répertoire du fournisseur, mais cela incombe au développeur de se rappeler d'exécuter vgo mod -vendor chaque fois que go.mod change, sinon l'application ne se construira pas et il devra exécuter vgo mod -vendor avant de réessayer. le docker construit.

Pouvez-vous penser à un moyen pour moi d'avoir un comportement comme mon imaginaire vgo install_dependencies? Est-ce que je manque un truc de vgo?

7
llimllib

tl; dr: Dans les versions actuelles go master et futures, go mod download fera ce travail. Pour l'instant, vous avez besoin d'un hack.

Sur le gophers slack, on m'a référé à cette question: https://github.com/golang/go/issues/26610 où j'ai appris que cela ferait plus ou moins ce que je veux (en supposant que vous ' en utilisant go version 1.11beta3):

# Populate the module cache based on the go.{mod,sum} files.
COPY go.mod .
COPY go.sum .
RUN go list -e $(go list -f '{{.Path}}' -m all)

Plus tard dans la discussion, Russ Cox implémentera go mod download, qui sera disponible dans la prochaine version de go, me permettant de supprimer le stupide go list hack ci-dessus.

2
llimllib

J'ai eu exactement le même problème, je voulais rendre la mise en cache de Docker plus précise.

Donc, je viens d'écrire mon propre outil pour cela: https://github.com/gladkikhartem/gomodget

Maintenant, mes pipelines docker-in-docker ne durent que 10 secondes et le journal de construction du docker se présente comme suit:

Step 4/15 : RUN go get -u golang.org/x/vgo
 ---> Using cache
 ---> 12c672a07a16
Step 5/15 : RUN go get github.com/gladkikhartem/gomodget
 ---> Using cache
 ---> acc70fea0edc
Step 7/15 : COPY go.mod .
 ---> Using cache
 ---> 41bae1ca7428
Step 8/15 : RUN gomodget
 ---> Using cache
 ---> 758100f7dde2
Step 9/15 : COPY . .
 ---> cc833c5bc810
Step 10/15 : RUN vgo build -ldflags '-extldflags "-static"' -o /bin/app 
1
Artem Co