Google app engine 我如何让自动售货机与谷歌应用程序引擎一起工作?
我试图将Go vendoring(将依赖项存储在名为Google app engine 我如何让自动售货机与谷歌应用程序引擎一起工作?,google-app-engine,go,Google App Engine,Go,我试图将Go vendoring(将依赖项存储在名为vendor的文件夹中)引入现有的应用程序引擎项目。我已将所有依赖项存储在供应商文件夹中(使用Godep作为帮助程序),看起来不错,但在本地运行应用程序时,我会遇到以下错误: go-app-builder:解析输入失败:包“golang.org/x/net/context”从多个位置导入:“/Users/erik/go/src/github.com/xyz/abc/vendor/golang.org/x/net/context”和“/Users
vendor
的文件夹中)引入现有的应用程序引擎项目。我已将所有依赖项存储在供应商文件夹中(使用Godep作为帮助程序),看起来不错,但在本地运行应用程序时,我会遇到以下错误:
go-app-builder:解析输入失败:包“golang.org/x/net/context”从多个位置导入:“/Users/erik/go/src/github.com/xyz/abc/vendor/golang.org/x/net/context”和“/Users/erik/go/src/golang.org/x/net/context”
我认为这两个位置应该解析为同一位置,因为Go应用程序应该首先查看
供应商
文件夹。有没有办法让Appengine明白这两个依赖项是相同的?实际上我自己也遇到了这个问题。当您使用App Engine工具构建任何导入使用vendoring的内容的包,但您尝试运行的包的供应商目录中没有导入内容时,就会出现问题
例如,如果我试图运行packagefoo
,它导入packagebar
,并且两者都使用github.com/gorilla/mux
库,如果bar
存储库有一个包含gorilla/mux的vendor/
目录,但是foo
包的vendor/
目录中没有gorilla mux,将发生此错误
发生这种情况的原因是,bar
包将优先考虑自己的供应商
包,而不是GOPATH
中的包,这是foo
将使用的,导致导入路径的实际位置不同
我找到的解决方案是确保foo
目录位于GOPATH
中,并且正确安装了供应商目录。需要注意的是,vendor/
约定仅在GOPATH
中起作用,您的项目目录(app.yaml所在的位置)可能位于GOPATH/src中。
不应该这样。
go app builder将获取app.yaml文件夹(及以下)中的所有内容,并将您的GOPATH合并到其中,这意味着您现在拥有它两次
解决方案是将app.yaml移出GOPATH/src文件夹。
此外,在解决依赖关系时,您会发现goapp-test
的工作方式与goapp-service
和goapp-deploy
不同
这就是我一直在使用的解决方案(有一段时间没有使用golang app engine),它是我发现的唯一一个可以正常运行所有goapp
命令和govendo
的设置(不确定godep
)
详情:
file: GOPATH/appengine/aeloader.go (NOTE the init function is necessary, probably a bug though)
package mypackage
import (
_ "MYPROJECT"
)
func init() {
}
现在运行goapp-service
和goapp-deploy
from。
和goapp-test./…
from。/GOPATH/src/MYPROJECT
另外,我觉得全局GOPATH很愚蠢,只需将我的GOPATH设置为当前项目文件夹(在上面的示例中)并将整个内容检查到版本控制中。我使用Govendo而不是Godeps解决了这个错误。根本原因似乎是Godeps未正确解决供应商引用及其自身供应商引用 Su Au Hwang提供的答案也是正确的——你必须将app.yaml与你的来源分开。也有同样的问题。 在本文中,谷歌建议如下: 为获得最佳效果,我们建议如下:
- 在应用程序的目录中为每个服务创建单独的目录
- 每个服务的目录都应该包含服务的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
文件夹包含所有依赖项。
从app.yaml
文件所在的myproject
目录运行gcloud deploy
不起作用,因为第一个main.go
文件不在同一目录下,第二个(来自同一文档):
您必须小心,不要将源代码放在app.yaml文件所在的应用程序目录下
我最终做的是构建自己的自定义运行时,这是一个非常干净的解决方案。只需使用以下命令生成
Dockerfile
:
gcloud beta app gen-config --custom
修改它,然后在app.yaml
中指定runtime:custom
,并正常部署。这里的诀窍当然是你可以控制在哪里复制什么。
这是我的
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"]
不要忘记,应用程序引擎希望您的应用程序监听端口8080。查看doc了解更多详细信息。我使用Makefile将
供应商
目录移动到临时的GOPATH
:
TMPGOPATH := $(shell mktemp -d)
deploy:
mv vendor $(TMPGOPATH)/src
GOPATH=$(TMPGOPATH) gcloud app deploy
mv $(TMPGOPATH)/src vendor
我将此Makefile
存储在vendor
目录附近的我的服务根目录中,只需使用makedeploy
手动或从CI进行部署
它与Glide、Godeps或任何遵守Go供应商规范的工具一起使用
请注意,您确实需要将
供应商
目录移出构建目录,否则GoAppEngine编译器将尝试构建供应商依赖项,这可能会导致编译错误 我在过去见过这个问题,通常通过确保我正在构建的存储库的所有供应商
目录都已正确设置来解决。你运行的命令是什么
TMPGOPATH := $(shell mktemp -d)
deploy:
mv vendor $(TMPGOPATH)/src
GOPATH=$(TMPGOPATH) gcloud app deploy
mv $(TMPGOPATH)/src vendor