AppEngine 部署找不到 Go 包
AppEngine deploy cannot find Go packages
我在 monorepo 中设置了一个 AppEngine 微服务,服务之间有共享代码,所以我重构以统一我的 go 模块(它们非常相似)。重构在本地工作,构建和 运行s,Goland 编译愉快。我的问题是 AppEngine 部署不再有效,
收到错误,例如:
Error message: cmd/main.go:4:2: cannot find package "github.com/gin-gonic/gin" in any of:
/usr/local/go/src/github.com/gin-gonic/gin (from $GOROOT)
/layers/google.go.appengine_gopath/gopath/src/github.com/gin-gonic/gin (from $GOPATH)
cmd/main.go:5:2: cannot find package "mymodulename/customer/internal/mypkg" in any of:
/usr/local/go/src/mymodulename/customer/internal/cauth (from $GOROOT)
/layers/google.go.appengine_gopath/gopath/src/mymodulename/customer/internal/mypkg (from $GOPATH)
原结构
> svc1
> cmd/main.go
> internal
>utils/shared.go
>mypkg
> go.mod
> app.yaml
> svc2
> cmd/main.go
> internal
>utils/shared.go
>mypkg
> go.mod
> app.yaml
重构后
> svc1
> cmd/main.go
> internal
>mypkg
> app.yaml
> svc2
> cmd/main.go
> internal
>mypkg
> app.yaml
> internal (common shared stuff)
> utils/shared.go
go.mod
重点是utils/shared.go 被移到每个服务目录之外并且go.mod 被统一了。
我不清楚的是 AppEngine 是否在我 运行 glcoud app deploy
时在我的本地计算机上构建 go 二进制文件,或者是否捆绑了所有内容并 运行 在云构建中将其打包。
- AppEngine 部署如何工作?
- 如何部署 AppEngine 以找到我的 go.mod 文件?
- 如何捆绑依赖项? (如果它在 CloudBuild 上 运行ning 肯定无法访问私有存储库)
回复您的问题:
AppEngine 部署如何工作?
- 您的源文件已上传到 Google 云存储。 Cloud Build 构建您的应用程序并将其部署到 App Engine。
如何部署 AppEngine 以找到我的 go.mod 文件?
- 您将模块的 go.mod 文件放在与 app.yaml 文件相同的目录中。
如何捆绑依赖项?
- 确实是运行 Cloud Build。 App Engine 无法在构建过程中下载您的私有依赖项,因此您必须在部署时将它们包含在您的应用程序代码中。详细信息可在“指定依赖项”文档页面的 Using private dependencies 段落中找到。
关于文件结构的重构:文件结构需要遵守 Structuring your files 段落中给出的规定:
- go-app/:Go 1.11 服务的目录。
- app.yaml:您的服务配置设置。
- main.go: 您的申请代码。
我为遇到相同问题的其他人提供的解决方案。
似乎存在一些事实,尽管文档对此有些模棱两可。
docs 说:
Create your module's go.mod file in the same directory as your app.yaml file. App Engine searches the current directory, then successive parent directories until it finds a go.mod file.
但这似乎不是真的,事实上,app.yaml 文件上面似乎没有任何内容被复制。
所以解决方案需要:
- 每个微服务都有自己的 go.mod 文件。
- go.mod 文件与 app.yaml
在同一目录中
go mod edit
用于告诉 Go 编译器在本地查找而不是尝试通过互联网获取。
- Vendoring 用于将所有依赖项捆绑在与 app.yaml 相同的目录中,以便将它们部署到 AppEngine。
关于本地进口的一些知识
Go 似乎首先在依赖项缓存/路径中查找所有内容,然后完全在 Internet 上查找。
如果我使用 go mod init shared
创建我的本地包,它的模块名称是 'shared'。
要告诉 Go 你想在本地导入而不是使用互联网,请调用 go mod edit -replace=shared=../../shared/
,
你应该看到你的 go.mod 得到了像 replace shared => ../../shared
这样的一行。
如果您使用的是 Goland 但它仍未编译,请尝试 File>Invalidate Caches/Restart...
一些关于销售的知识
go mod vendor
在您的 go.mod 文件夹中将捆绑所有依赖项,包括本地依赖项,以便 AppEngine 可以部署它们。这也是处理私有存储库的好方法,因此您不需要 git Cloud Build 访问您的存储库。
我在 monorepo 中设置了一个 AppEngine 微服务,服务之间有共享代码,所以我重构以统一我的 go 模块(它们非常相似)。重构在本地工作,构建和 运行s,Goland 编译愉快。我的问题是 AppEngine 部署不再有效, 收到错误,例如:
Error message: cmd/main.go:4:2: cannot find package "github.com/gin-gonic/gin" in any of:
/usr/local/go/src/github.com/gin-gonic/gin (from $GOROOT)
/layers/google.go.appengine_gopath/gopath/src/github.com/gin-gonic/gin (from $GOPATH)
cmd/main.go:5:2: cannot find package "mymodulename/customer/internal/mypkg" in any of:
/usr/local/go/src/mymodulename/customer/internal/cauth (from $GOROOT)
/layers/google.go.appengine_gopath/gopath/src/mymodulename/customer/internal/mypkg (from $GOPATH)
原结构
> svc1
> cmd/main.go
> internal
>utils/shared.go
>mypkg
> go.mod
> app.yaml
> svc2
> cmd/main.go
> internal
>utils/shared.go
>mypkg
> go.mod
> app.yaml
重构后
> svc1
> cmd/main.go
> internal
>mypkg
> app.yaml
> svc2
> cmd/main.go
> internal
>mypkg
> app.yaml
> internal (common shared stuff)
> utils/shared.go
go.mod
重点是utils/shared.go 被移到每个服务目录之外并且go.mod 被统一了。
我不清楚的是 AppEngine 是否在我 运行 glcoud app deploy
时在我的本地计算机上构建 go 二进制文件,或者是否捆绑了所有内容并 运行 在云构建中将其打包。
- AppEngine 部署如何工作?
- 如何部署 AppEngine 以找到我的 go.mod 文件?
- 如何捆绑依赖项? (如果它在 CloudBuild 上 运行ning 肯定无法访问私有存储库)
回复您的问题:
AppEngine 部署如何工作?
- 您的源文件已上传到 Google 云存储。 Cloud Build 构建您的应用程序并将其部署到 App Engine。
如何部署 AppEngine 以找到我的 go.mod 文件?
- 您将模块的 go.mod 文件放在与 app.yaml 文件相同的目录中。
如何捆绑依赖项?
- 确实是运行 Cloud Build。 App Engine 无法在构建过程中下载您的私有依赖项,因此您必须在部署时将它们包含在您的应用程序代码中。详细信息可在“指定依赖项”文档页面的 Using private dependencies 段落中找到。
关于文件结构的重构:文件结构需要遵守 Structuring your files 段落中给出的规定:
- go-app/:Go 1.11 服务的目录。
- app.yaml:您的服务配置设置。
- main.go: 您的申请代码。
我为遇到相同问题的其他人提供的解决方案。 似乎存在一些事实,尽管文档对此有些模棱两可。 docs 说:
Create your module's go.mod file in the same directory as your app.yaml file. App Engine searches the current directory, then successive parent directories until it finds a go.mod file.
但这似乎不是真的,事实上,app.yaml 文件上面似乎没有任何内容被复制。
所以解决方案需要:
- 每个微服务都有自己的 go.mod 文件。
- go.mod 文件与 app.yaml 在同一目录中
go mod edit
用于告诉 Go 编译器在本地查找而不是尝试通过互联网获取。- Vendoring 用于将所有依赖项捆绑在与 app.yaml 相同的目录中,以便将它们部署到 AppEngine。
关于本地进口的一些知识
Go 似乎首先在依赖项缓存/路径中查找所有内容,然后完全在 Internet 上查找。
如果我使用 go mod init shared
创建我的本地包,它的模块名称是 'shared'。
要告诉 Go 你想在本地导入而不是使用互联网,请调用 go mod edit -replace=shared=../../shared/
,
你应该看到你的 go.mod 得到了像 replace shared => ../../shared
这样的一行。
如果您使用的是 Goland 但它仍未编译,请尝试 File>Invalidate Caches/Restart...
一些关于销售的知识
go mod vendor
在您的 go.mod 文件夹中将捆绑所有依赖项,包括本地依赖项,以便 AppEngine 可以部署它们。这也是处理私有存储库的好方法,因此您不需要 git Cloud Build 访问您的存储库。