2016-10-31 3 views
5

Ich versuche, einen Andock-Container mit Kreditor auszuführen. Das ist mein DockerfileGodep Vendor mit Docker

FROM golang:alpine 
EXPOSE 8080 

RUN mkdir /app 
ADD . /app/ 
WORKDIR /app 
RUN go build -o myapp . 
CMD ["/app/myapp"] 

und meine main.go

package main 

import (
    "fmt" 
    "log" 
    "net/http" 

    "github.com/gorilla/mux" 
) 

func main() { 

    r := mux.NewRouter() 
    r.HandleFunc("/", Hello) 

    http.Handle("/", r) 
    fmt.Println("Starting up on 8080") 
    log.Fatal(http.ListenAndServe(":8080", nil)) 
} 

func Hello(w http.ResponseWriter, req *http.Request) { 
    fmt.Fprintln(w, "Hello world!") 
} 

Ich verwende godep Libs für vendoring, es funktioniert in meinem lokalen Rechner, aber wenn ich versuche, es zu laufen mit docker mit:

docker build -t myapp-img . 
docker run -p 8080:8080 --name myapp-cnt myapp-img 

ich habe folgende Fehlermeldung:

main.go:8:2: cannot find package "github.com/gorilla/mux" in any of: 
     /usr/local/go/src/github.com/gorilla/mux (from $GOROOT) 
     /go/src/github.com/gorilla/mux (from $GOPATH) 

Ich verstehe nicht, was fehlt.

Antwort

4

Der Fehler ist korrekt. Es erzählt dir alles, was ein aufstrebender Gopher braucht.

Ich gehe davon aus, dass Sie in Ihrem lokalen Rechner Gorilla Mux zu Ihrer App/Lieferantenverzeichnis kopiert haben, etwa so:

./main.go # this is your myapp code you are coping 
./vendor/github.com/gorilla/mux # for vendoring, this must exist 

Wenn Sie mehr über vendoring erfahren möchten, sehen meine populäre Antwort hier :

How should I use vendor in Go 1.6?

, Nimmt man nun an, dass die Fehler beheben Sie die oben ...

Ein Gopher muss se getan haben t eine gültige $GOPATH bevor Sie bauen können. Dies fehlt in Ihrer Dockerfile.

FROM golang:1.7-alpine 
EXPOSE 8080 

# setup GOPATH and friends 
# 
# TECHNICALLY, you don't have to do these three cmds as the 
# golang:alpine image actually uses this same directory structure and 
# already has $GOPATH set to this same structure. You could just 
# remove these two lines and everything below should continue to work. 
# 
# But, I like to do it anyways to ensure my proper build 
# path in case I experiment with different Docker build images or in 
# case the #latest image changes structure (you should really use 
# a tag to lock down what version of Go you are using - note that I 
# locked you to the docker image golang:1.7-alpine above, since that is 
# the current latest you were using, with bug fixes). 
# 
RUN mkdir -p /go/src \ 
    && mkdir -p /go/bin \ 
    && mkdir -p /go/pkg 
ENV GOPATH=/go 
ENV PATH=$GOPATH/bin:$PATH 

# now copy your app to the proper build path 
RUN mkdir -p $GOPATH/src/app 
ADD . $GOPATH/src/app 

# should be able to build now 
WORKDIR $GOPATH/src/app 
RUN go build -o myapp . 
CMD ["/go/src/app/myapp"] 

Hier funktioniert es ...

$ tree 
. 
├── Dockerfile 
├── main.go 
└── vendor 
    └── mydep 
     └── runme.go 

Die Quelldatei meiner App:

$ cat main.go 
package main 

import (
     "fmt" 

     "mydep" 
) 

func main() { 
     fmt.Println(mydep.RunMe()) 
} 

Meine Abhängigkeit in meinem vendor/ Ordner:

$ cat vendor/mydep/runme.go 
package mydep 

// RunMe returns a string that it worked! 
func RunMe() string { 
     return "Dependency Worked!" 
} 

Jetzt , erstellen und führen Sie das Image:

$ docker build --rm -t test . && docker run --rm -it test 
(snip) 
Step 8 : WORKDIR $GOPATH/src/app 
---> Using cache 
---> 954ed8e87ae0 
Step 9 : RUN go build -o myapp . 
---> Using cache 
---> b4b613f0a939 
Step 10 : CMD /go/src/app/myapp 
---> Using cache 
---> 3524025080df 
Successfully built 3524025080df 
Dependency Worked! 

Beachten Sie die letzte Zeile, die die Ausgabe von der Konsole druckt, Dependency Worked!.

Es funktioniert, weil:

  1. Sie erklären Sie Vendoring verwenden, das heißt, Sie haben ein lokales Verzeichnis ./vendor in der Wurzel Ihres Anwendungscode aufgerufen.
  2. Wenn Sie ADD . /go/src/app, kopieren Sie auch die ./vendor lokal zu Ihrem Anwendungscode.
  3. Sie haben Ihre Dateien in die richtige $GOPATH Setup-Struktur kopiert, die von den Go Build-Tools benötigt wird, um Pakete zu finden (und in diesem Fall das Verzeichnis ./vendor im Stammverzeichnis Ihres Quellcodes).
+0

Thx für die Antwort, ich habe versucht, Ihre Dockerfile zu verwenden, aber wenn ich den docker run-Befehl ausführen, sieht es aus wie die GOPATH nicht festgelegt ist. 'Fehler Antwort von Daemon: Oci Laufzeitfehler: exec:" $ GOPATH/src/app/myapp ": stat $ GOPATH/src/app/myapp: keine solche Datei oder Verzeichnis.' – sbouaked

+0

repariert die Dockerfile ($ GOPATH isn ' t verfügbar für CMD). fügte auch ein vollständiges Arbeitsbeispiel hinzu (jetzt, wo ich mit einem Laptop arbeite). – eduncan911

Verwandte Themen