我试图与供应商一起运行docker容器。 这是我的Dockerfile
FROM golang:alpine
EXPOSE 8080
RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN go build -o myapp .
CMD ["/app/myapp"]
和我的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!")
}
我使用godep来销售libs,它在我的本地机器上工作,但是当我试图用docker运行它时:
docker build -t myapp-img .
docker run -p 8080:8080 --name myapp-cnt myapp-img
我有以下错误:
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)
我不明白缺少什么。
答案 0 :(得分:4)
错误是正确的。它告诉你一个有抱负的Gopher需要的一切。
我将假设您已将Gorilla Mux复制到本地计算机上的应用程序/供应商目录中,如下所示:
./main.go # this is your myapp code you are coping
./vendor/github.com/gorilla/mux # for vendoring, this must exist
如果您想了解更多有关vendoring的信息,请参阅我在这里的热门答案:
How should I use vendor in Go 1.6?
现在,假设您已完成上述操作,修复该错误......
Gopher需要在构建之前设置有效的$GOPATH
。 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"]
这是工作......
$ tree
.
├── Dockerfile
├── main.go
└── vendor
└── mydep
└── runme.go
我的应用的源文件:
$ cat main.go
package main
import (
"fmt"
"mydep"
)
func main() {
fmt.Println(mydep.RunMe())
}
我在vendor/
文件夹中的依赖关系:
$ cat vendor/mydep/runme.go
package mydep
// RunMe returns a string that it worked!
func RunMe() string {
return "Dependency Worked!"
}
现在,构建并运行图像:
$ 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!
请注意从控制台Dependency Worked!
打印输出的最后一行。
它的工作原因是:
./vendor
的本地目录。ADD . /go/src/app
时,您还要将./vendor
本地文件复制到您的应用程序代码中。$GOPATH
设置结构中,以查找包(在本例中为源代码根文件夹中的./vendor
目录)。