J'ai mon Dockerfile à la racine du répertoire avec src/myapp
dossier, myapp
contient myapp.go
avec le package principal.
Dockerfile
ressemble à ceci:
FROM golang:1.9.2
ADD . /
RUN go build myapp;
ENTRYPOINT ["/go/bin/myapp"]
J'obtiens l'erreur suivante:
can't load package: package myapp: cannot find package "myapp" in any of:
/usr/local/go/src/myapp (from $GOROOT)
/go/src/myapp (from $GOPATH)
Qu'est-ce que je fais mal? Puis-je enregistrer la commande ls
une fois que le docker a terminé ADD
?
Vous copiez tous les fichiers dans le répertoire racine de l'image, n'avez installé aucune dépendance, essayez de le créer, puis exécutez le binaire à partir de /go/bin/app
. Le binaire n'existe pas dans ce répertoire et il génère des erreurs.
Je recommanderais d'utiliser un Dockerfile comme celui-ci,
FROM golang:1.9.2
ADD . /go/src/myapp
WORKDIR /go/src/myapp
RUN go get myapp
RUN go install
ENTRYPOINT ["/go/bin/myapp"]
Cela fera ce qui suit.
/go/src/myapp
./go/src/myapp
.Vous pouvez exécuter ls
ou toute autre commande à l'aide de docker exec
.
Exemple:
docker exec <image name/hash> ls
Vous pouvez également saisir le Shell dans l'image générée pour bien le comprendre en utilisant
docker run --rm -it <image hash/name> /bin/sh
Après des expériences, je suis arrivé à cette façon de créer des applications Golang.
Cette façon présente plusieurs avantages:
les dépendances sont installées à l'étape de la construction
si vous en avez besoin, vous pouvez décommenter les options de test
créer la première image entièrement fonctionnelle d'environ 800 Mo
copie votre programme sur une nouvelle image vide et produit une très petite image d'environ 10 Mo
Dockerfile
:
# Two-stage build:
# first FROM prepares a binary file in full environment ~780MB
# second FROM takes only binary file ~10MB
FROM golang:1.9 AS builder
RUN go version
COPY . "/go/src/github.com/your-login/your-project"
WORKDIR "/go/src/github.com/your-login/your-project"
#RUN go get -v -t .
RUN set -x && \
#go get github.com/2tvenom/go-test-teamcity && \
go get github.com/golang/dep/cmd/dep && \
dep ensure -v
RUN CGO_ENABLED=0 GOOS=linux GOARCH=AMD64 go build -o /your-app
CMD ["/your-app"]
EXPOSE 8000
#########
# second stage to obtain a very small image
FROM scratch
COPY --from=builder /your-app .
EXPOSE 8000
CMD ["/your-app"]
Pour go 1.11, vous pouvez utiliser le module go, ce qui suit est un exemple
FROM Alpine AS base
RUN apk add --no-cache curl wget
FROM golang:1.11 AS go-builder
WORKDIR /go/app
COPY . /go/app
RUN GO111MODULE=on CGO_ENABLED=0 GOOS=linux GOARCH=AMD64 go build -o /go/app/main /go/app/cmd/myapp/main.go
FROM base
COPY --from=go-builder /go/app/main /main
CMD ["/main"]
myapp
doit être dans /go/src/myapp
comme suggéré, ou dans /usr/local/go/src/myapp
. Vous pouvez l'ajouter dans la section ADD
.
Les documents officiels suggèrent le Dockerfile suivant:
FROM golang:1.8
WORKDIR /go/src/app
COPY . .
RUN go get -d -v ./...
RUN go install -v ./...
CMD ["app"]
Veuillez visiter https://hub.docker.com/_/golang pour plus d'informations
Si l'objectif est de créer un conteneur qui exécute simplement votre binaire, j'opterais pour une approche différente.
Construisez d'abord le binaire pour linux:
GOOS=linux CGO_ENABLED=0 go build -a -installsuffix cgo
Créez ensuite une image docker légère à partir de zéro:
FROM scratch
COPY myApp
CMD ["/myApp"]