如何使用Google App Engine进行销售?

时间:2016-10-09 20:07:38

标签: google-app-engine go

我正在尝试将Go vendoring(将依赖项存储在名为vendor的文件夹中)引入现有的App Engine项目。我已将所有依赖项存储在vendor文件夹中(使用Godep作为帮助程序)并且看起来正确,但在本地运行应用程序时出现以下错误:

go-app-builder: Failed parsing input: package "golang.org/x/net/context" is imported from multiple locations: "/Users/erik/go/src/github.com/xyz/abc/vendor/golang.org/x/net/context" and "/Users/erik/go/src/golang.org/x/net/context"

我相信这两个位置应该解析到同一个位置,因为Go应用程序应首先查看vendor文件夹。有没有办法让Appengine明白两个依赖都是一样的?

5 个答案:

答案 0 :(得分:9)

您的项目目录(app.yaml所在的位置)可能位于GOPATH / src中。 它不应该。 go-app-builder将把app.yaml文件夹(及其下方)中的所有内容都包含在内,并将GOPATH合并到其中,这意味着现在你有两次。

解决方案是将app.yaml移出GOPATH / src文件夹。 此外,在解决依赖关系时,您会发现goapp testgoapp servegoapp deploy的工作方式不同。

所以这是我一直在使用的解决方案(暂时没有使用golang app引擎),这是我发现的唯一设置,可以正常运行所有goapp命令和{{ 1}}正常工作(不确定govendor

godep

细节:

/GOPATH
├──/appengine
|   ├── app.yaml
|   └── aeloader.go
└──/src
    └── /MYPROJECT
         ├── main.go
         ├── /handler
         |    └── handler.go
         └── /vendor

现在来自file: GOPATH/appengine/aeloader.go (NOTE the init function is necessary, probably a bug though) package mypackage import ( _ "MYPROJECT" ) func init() { } 的{​​{1}}和goapp serve以及来自goapp deploy的{​​{1}}

P.S。我发现全局GOPATH的事情很愚蠢,只需将我的GOPATH设置为当前项目文件夹(在上面的示例中为../GOPATH/appengine/)并将整个内容检查为版本控制。

答案 1 :(得分:7)

我使用Makefile将vendor目录移动到临时GOPATH

TMPGOPATH := $(shell mktemp -d)

deploy:
  mv vendor $(TMPGOPATH)/src
  GOPATH=$(TMPGOPATH) gcloud app deploy
  mv $(TMPGOPATH)/src vendor 

我将此Makefile存储在vendor目录附近的服务根目录中,只需使用make deploy手动部署或从CI部署。

适用于Glide,Godeps或任何尊重Go供应商规范的工具。

请注意,您确实需要将vendor目录移出构建目录,否则GoAppEngine编译器将尝试构建供应商依赖项,从而可能导致编译错误。

答案 2 :(得分:1)

我实际上是自己遇到过这个问题。当您使用App Engine工具构建任何导入正在使用vendoring的内容的软件包时会出现问题,但您尝试运行的软件包并未在其中导入。供应商目录。

因此,例如,如果我尝试运行包foo,导入包bar,并且两者都使用github.com/gorilla/mux库,如果{{} 1}} repository有一个包含gorilla / mux的bar目录,但vendor/包中没有gorilla mux的foo目录,这个错误会发生。

发生这种情况的原因是,vendor/包会优先考虑它自己的bar包,而不是vendor中的GOPATH包。foo使用,导致导入路径的实际位置不同。

我发现此问题的解决方案是确保foo目录位于GOPATH并正确安装了供应商目录。值得注意的是,vendor/惯例仅适用于GOPATH

答案 3 :(得分:1)

我设法使用govendor而不是Godeps来解决此错误。根本原因似乎是Godeps无法正确解析带有自己的销售参考的销售参考。

Su-Au Hwang提供的答案也是正确的 - 你必须将app.yaml与你的来源分开。

答案 4 :(得分:1)

也遇到了同样的问题。 在docs Google建议如下:

  

为获得最佳效果,我们建议如下:

     
      
  • 在应用目录中为每项服务创建一个单独的目录。
  •   
  • 每个服务的目录应包含服务的app.yaml文件和一个或多个.go文件。
  •   
  • 不要在服务目录中包含任何子目录。
  •   
  • 您的GOPATH应指定一个位于您应用目录之外的目录,并包含您的应用导入的所有依赖项。
  •   

但这会弄乱我的项目结构,看起来像这样:

GOPATH/
└── src
    └── github.com
        └── username
            └── myproject
                ├── app.yaml
                ├── cmd
                │   └── myproject
                │       └── main.go
                ├── handlers
                │   └── api.go
                ├── mw
                │   ├── auth.go
                │   └── logger.go
                └── vendor

myproject目录是git项目,vendor文件夹包含所有依赖项。 从gcloud deploy文件所在的myproject目录运行app.yaml不起作用,因为第一个main.go文件不在同一目录中,第二个(来自同一个文档):

  

您必须小心,不要将源代码放在app.yaml文件所在的应用程序目录下面或下面

我最终做的是建立自己的自定义运行时,结果证明这是一个非常干净的解决方案 只需使用以下命令生成Dockerfile

gcloud beta app gen-config --custom

修改它,然后在runtime: custom中指定app.yaml并正常部署 这里的诀窍当然是你可以控制被复制的地方 这是我的Dockerfile

# Dockerfile extending the generic Go image with application files for a
# single application.
FROM gcr.io/google-appengine/golang

ENV GOPATH /go

# The files which are copied are specified in the .dockerignore file
COPY . /go/src/github.com/username/myproject/

WORKDIR /go/src/github.com/username/myproject/

RUN go build -o dist/bin/myproject ./cmd/myproject

# All configuration parameters are passed through environment variables and specified in app.yaml
CMD ["/go/src/github.com/username/myproject/dist/bin/myproject"]

不要忘记App Engine希望您的应用程序在端口8080上进行侦听。有关详细信息,请查看Building Custom Runtimes doc。