为什么 Google App Engine Standard 不提供预编译资产?

Why aren't precompiled assets served on Google App Engine Standard?

我在标准环境中的 Rails GAE 应用 运行 上有一个 Ruby。当我使用监视我的 git 集线器存储库的 Cloudbuild 进行部署时,我可以看到它在构建日志中预编译资产并将它们存储在 /workspace/public/assets 中,正如预期的那样。只有当我的回购协议中也没有预编译资产时才会发生这种情况,否则构建日志会显示:

Step #3 - "detector": ======== Output: google.ruby.rails@0.9.0 ========
Step #3 - "detector": Rails assets do not need precompilation.
Step #3 - "detector": ======== Results ========

我的部署云构建步骤是

  - id: deploy_to_GAE
    name: gcr.io/cloud-builders/gcloud
    args: ['app', 'deploy', '--project', '${PROJECT_ID}', '--version', '${BRANCH_NAME}', '${_APP_CONFIG}']

我的 app.yaml

中也有这个处理程序
handlers:
  - url: /(.*\.(gif|png|jpg|ico|html|txt|webmanifest))$
    static_files: public/

但是,在部署之后,可以加载 none 的静态资产 - 它们都会收到 404 响应并且服务器日志显示如下内容: Static file referenced by handler not found: public/assets/star_custom3-bf067f238ca10c6a873fd0bdd42e55a22f65a9842f010d10e55e2e4acb12ae5b.png

但是,如果我在本地预编译,并将预编译的静态文件推送到我的 git 存储库,那么 Cloud Build 仍然会成功部署(并且不会按照上述再次预编译资产),并且所有资产都会正确加载在我的浏览器中。

在这两种情况下,如果我“调试”部署在 GAE 的 Web 控制台中的版本,我可以看到实际部署了哪些文件,并且可以在 /public/assets 中正确地看到它们。然而只有在后一种情况下,Web 浏览器才能访问它们。

我还尝试在 cloudbuild.yaml 中添加构建步骤,以使用自定义 Cloud Builder 容器预编译资产。它按预期在 /workspace 中创建资产,但出于某种原因,上面的 depoly_to_GAE 步骤重新预编译了它们。

最后,如果我在本地删除所有预编译资产,然后手动部署到 GAE gcloud app deploy app-ticket.yaml --project={my project},Cloud Build 日志显示它正在预编译,就像上面一样,网络浏览器无法访问资产(404 错误)

deploy_to_GAE 构建步骤预编译资产时,它还会设置 RAILS_ENV=production,但是,其余部署的实际环境和 app.yaml 文件中设置的 env var是 RAILS_ENV=staging。不过我认为这无关紧要。

为什么 GAE 的内置资产预编译器会生成可用的静态资产?

更新: 即使在使用 gcloud app deploy 且没有 /public/assets 文件夹的本地部署时,我也可以看到 cloudbuild 将编译资产,并且 appear 将它们正确地放在 /public/assets :

但是,当使用 the GCP Debugger 时,我注意到路径在文件夹名称中使用文字“/”而不是创建子文件夹。这似乎是 GAE 构建器中的一个缺陷:

我希望“assets”文件夹正确嵌套在“public”下,而不是名为“public/assets”的突变文件夹。

这个问题更适合 Google Cloud Support,因为它更容易调查并获得正确和彻底的答案,也更容易使用他们的工具检查项目并获得有关该问题的更好支持。

事实证明,GAE 对预编译资产做了一些未记录的魔术,不仅在构建时自动预编译它们,而且还通过创建到这些资产的路由而无需在 app.yaml 中添加处理程序。一旦我删除了主要问题中的处理程序显示(并在下面复制),那么一切都按预期工作:如果我没有 /public/assets 文件夹,那么 gcloud app deploy 会自动预编译资产,只要我没有'尝试创建一个处理程序,然后它将正确地为这些资产提供服务。