我正在尝试与 vendor 一起运行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来供应库,它在我的本地计算机上工作,但是当我尝试通过docker与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)

我不明白缺少了什么。

最佳答案

错误是正确的。它告诉您有抱负的Gopher所需要的一切。

我将假设您已将Gorilla Mux复制到本地计算机中应用程序的/vendor目录中,如下所示:

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

如果您想了解有关 vendor 的更多信息,请在此处查看我的热门答案:

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!

之所以有效,是因为:

您声明自己正在使用Vendoring的
  • ,这意味着您在应用程序代码的根目录中有一个名为./vendor的本地目录。
  • 当您使用ADD . /go/src/app时,您还将本地./vendor复制到您的应用程序代码中。
  • 您已将文件复制到Go构建工具所需的正确$GOPATH设置结构中,以查找包(在本例中为源代码的根文件夹中的./vendor目录)。
  • 关于Godep vendor 与Docker,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40340860/

    10-12 22:15