无法 运行 Google App Engine 自定义托管 VM:--custom-entrypoint 必须设置错误
Cannot run Google App Engine custom managed VM: --custom-entrypoint must be set error
问题描述
我正在尝试为 Google App Engine 创建自定义托管 VM,其行为与 Google 提供的标准 python27 托管 VM 相同。 (我这样做是将 C++ 库添加到 运行 时间的第一步)。
来自googledocumentation,以下Dockerfile指定标准python27运行时间:
FROM gcr.io/google_appengine/python-compat
ADD . /app
我已经通过检查 gcloud preview app run
使用标准 python27 运行 时间生成的文件来验证这是正确的 Dockerfile。与此相同。
但是当我 运行 我的应用程序使用此 Dockerfile 使用 dev_appserver.py
或 gcloud preview app run
我收到一条错误消息:
The --custom_entrypoint flag must be set for custom runtimes
我正在使用最新版本的 gcloud(1.9.86,带有 app-engine-python 组件版本 1.9.28)和独立的 python 应用引擎 SDK (1.9.28) .我之前的版本也有同样的问题,所以我更新到最新的。
我尝试过的东西:
gcloud preview app run --help
关于 --custom-entrypoint
有以下说法:
--custom-entrypoint CUSTOM_ENTRYPOINT
Specify an entrypoint for custom runtime modules. This is required when
such modules are present. Include "{port}" in the string (without
quotes) to pass the port number in as an argument. For instance:
--custom_entrypoint="gunicorn -b localhost:{port} mymodule:application"
我不知道该怎么做。 docker 图像不应该包含 ENTRYPOINT 吗?为什么我需要另外提供一份?此外,gcr.io/google_appengine/python-compat
图像的入口点应该是什么? Google 没有为此提供文档。
我试过一个无意义的 --custom-entrypoint="echo"
,它可以消除错误,但应用程序不响应任何 HTTP 请求。
我发现的另外两个相关的 Whosebug 问题没有帮助。接受的答案似乎表明这是已解决的 SDK 中的错误。但是我在两个版本的SDK中都试过了,包括最新的,还是有问题。
重现步骤:
为了突出我的问题,我创建了一个生成错误的普通应用程序。它仅包含三个文件:
app.yaml
:
module: default
version: 1
runtime: custom
api_version: 1
threadsafe: true
vm: true
handlers:
- url: /.*
script: wsgi.app
Dockerfile
:
FROM gcr.io/google_appengine/python-compat
ADD . /app
这个 Dockerfile
与 python27 运行 时间使用的相同(实际上是从 gcloud preview app run
生成的 Dockerfile 中复制粘贴的使用 python27 运行 时间),因此这应该与设置 runtime: python27
.
相同
wsgi.py
:
import webapp2
class Hello(webapp2.RequestHandler):
def get(self):
self.response.write(u'Hello')
app = webapp2.WSGIApplication([('/Hello', Hello)], debug=True)
当我在包含这三个文件的目录中 运行 dev_appserver.py app.yaml
时,出现以下错误:
Traceback (most recent call last):
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 83, in <module>
_run_file(__file__, globals())
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 79, in _run_file
execfile(_PATHS.script_file(script_name), globals_)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1033, in <module>
main()
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1026, in main
dev_server.start(options)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 818, in start
self._dispatcher.start(options.api_host, apis.port, request_data)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 194, in start
_module.start()
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1555, in start
self._add_instance()
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1707, in _add_instance
expect_ready_request=True)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/custom_runtime.py", line 73, in new_instance
assert self._runtime_config_getter().custom_config.custom_entrypoint
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 383, in _get_runtime_config
raise ValueError('The --custom_entrypoint flag must be set for '
ValueError: The --custom_entrypoint flag must be set for custom runtimes
更新
这可能不再准确。查看尼克的回答。
(虽然我做不到,但我并没有很努力)
有一条完全没有记录但绝对必要的信息w.r.t。自定义托管 VM:
它们不能 运行 在开发服务器上!
如果您认为这个重要事实会在任何理智的地方被提及,比如自定义托管 VM 的文档页面,或 dev_appserver.py
,甚至 运行 dev_appserver.py
,那么您给 Google 太多的信任了。
我唯一能找到关于此的任何类型声明的地方是 github 上 appengine-java-vm-guestbook-extras demo 的自述文件(严肃地说):
The Cloud SDK does not support anymore running custom runtimes when a
Dockerfile is provided. You'll have to deploy the application to App
Engine
Google 不关心:
- 实施这一基本且重要的功能。
- 开发服务器缺少如此重要功能的文档。
- 当用户厌倦执行操作时给出任何合理的错误消息。
我希望这个答案能让一些遗憾的开发人员免于我因此而遭受的折磨。
编辑 1:由 user862857 编辑的解决方案 post 利用 Docker 本身构建图像来自 Docker 文件和 运行 它们在容器中。这也是在开发环境中 运行 管理 VM 和自定义运行时的好方法。
接受的答案似乎不正确。在处理快速发展的 Beta 产品时,github 自述文件的权威性不应胜过 official docs。使用 OP 的 post、
中提到的 Docker 文件,开发环境中的 runtime: custom
应用程序是完全可能的
FROM gcr.io/google_appengine/python-compat
ADD . /app
使用 --runtime=python-compat
标志。不过,他们需要捕获对 /_ah/start
和 /_ah/health
的请求。尝试 运行 以下命令,给定以下文件,并亲自查看:
devserver command
$ dev_appserver.py app.yaml --runtime=python-compat
app.yaml
runtime: custom
vm: true
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
Dockerfile
FROM gcr.io/google_appengine/python-compat
RUN apt-get update
RUN apt-get install -y gwhois
ADD . /app
main.py
import logging
import webapp2
from subprocess import Popen, PIPE
class OkHandler (webapp2.RequestHandler):
def get (self):
self.response.write ('ok')
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
domain = self.request.get ('domain')
cmd = ["gwhois", domain]
process = Popen (cmd, stdout=PIPE, stderr=PIPE)
output, err = process.communicate()
exit_code = process.wait()
self.response.write('stdout: %s' % output)
logging.info ('stderr: %s' % err)
app = webapp2.WSGIApplication([
('/', MainPage),
('/_ah/start', OkHandler),
('/_ah/health', OkHandler)
], debug=True)
向 /?domain=whosebug.com
发送请求以查看实际效果。
N.B.
如果他们希望完全脱离 python-compat 运行time 并简单地 deploy/test 通过 python WSGI 应用程序,他们也可以使用 --custom_entrypoint
标志,只要他们有一个命令可以在合适的端口上启动 运行ning 适当的 WSGI 应用程序(这样的命令将是 uwsgi or gunicorn)。
在尝试让我的自定义 VM 更好地与 dev_appserver 一起工作之后
一天的一部分,接受
对此 post 的回答 作为
非常不愉快的惊喜。但我认为部署开发服务器不会那么那么麻烦,因为毕竟 VM 是标准 Docker 映像。
好吧,确实有一些问题阻止了直接部署的工作。我在下面提供了这些问题的摘要以及我是如何解决它们的。我可能错过了 Docker 和 App Engine 环境之间的一些不兼容性(尤其是我的项目没有使用的 App Engine 的许多方面),但希望它足以让人们起来并 运行ning。
麻烦的来源
首先,我发现 Compute Engine 虚拟机中的 python 环境 运行 是一个
比普通的 VM 环境更宽松(例如 webapp2
之类的包总是可用的)。因此,部署到不太宽容的 Docker
容器环境在我的项目中出现了一些潜在错误。
也就是说,环境存在一些差异
即使您的项目完美无缺,也需要进行一些调整:
问题:gunicorn(或您选择的服务器)必须安装在
Docker 容器的路径。
- 虽然这看起来很明显,但我 运行 遇到了麻烦,因为我包括
gunicorn
在我项目的 requirements.txt
文件中。不幸的是,我是
使用只能安装源代码的 pip install -t ...
安装所有这些依赖项。结果,图像上没有 gunicorn
二进制文件,更不用说 PATH
.
解决方法:显式pip install gunicorn
- 问题:
google.appengine.*
软件包无法从
App Engine 基础 Docker 图像也无法通过 pip (AFAICT) 获得。
- 这可能是一个常见的问题来源,因为
google.appengine.ext.vendor
是将第三方库导入 App Engine 应用程序的推荐接口。
- 解决方案: 我通过下载整个 Google App Engine 包层次结构并将其放在应用程序的路径上来解决这个问题。
如何获取脚本
用于构建 VM docker 映像并将其部署到 docker 容器的脚本
运行ning 本地可用
here.
有关工作示例,请查看 my project。
如果您有任何评论、功能请求或写得更漂亮,请告诉我 bash
比我高(我觉得我在这方面把门槛定得很低)。
问题描述
我正在尝试为 Google App Engine 创建自定义托管 VM,其行为与 Google 提供的标准 python27 托管 VM 相同。 (我这样做是将 C++ 库添加到 运行 时间的第一步)。
来自googledocumentation,以下Dockerfile指定标准python27运行时间:
FROM gcr.io/google_appengine/python-compat
ADD . /app
我已经通过检查 gcloud preview app run
使用标准 python27 运行 时间生成的文件来验证这是正确的 Dockerfile。与此相同。
但是当我 运行 我的应用程序使用此 Dockerfile 使用 dev_appserver.py
或 gcloud preview app run
我收到一条错误消息:
The --custom_entrypoint flag must be set for custom runtimes
我正在使用最新版本的 gcloud(1.9.86,带有 app-engine-python 组件版本 1.9.28)和独立的 python 应用引擎 SDK (1.9.28) .我之前的版本也有同样的问题,所以我更新到最新的。
我尝试过的东西:
gcloud preview app run --help
关于 --custom-entrypoint
有以下说法:
--custom-entrypoint CUSTOM_ENTRYPOINT
Specify an entrypoint for custom runtime modules. This is required when
such modules are present. Include "{port}" in the string (without
quotes) to pass the port number in as an argument. For instance:
--custom_entrypoint="gunicorn -b localhost:{port} mymodule:application"
我不知道该怎么做。 docker 图像不应该包含 ENTRYPOINT 吗?为什么我需要另外提供一份?此外,gcr.io/google_appengine/python-compat
图像的入口点应该是什么? Google 没有为此提供文档。
我试过一个无意义的 --custom-entrypoint="echo"
,它可以消除错误,但应用程序不响应任何 HTTP 请求。
我发现的另外两个相关的 Whosebug 问题没有帮助。接受的答案似乎表明这是已解决的 SDK 中的错误。但是我在两个版本的SDK中都试过了,包括最新的,还是有问题。
重现步骤:
为了突出我的问题,我创建了一个生成错误的普通应用程序。它仅包含三个文件:
app.yaml
:
module: default
version: 1
runtime: custom
api_version: 1
threadsafe: true
vm: true
handlers:
- url: /.*
script: wsgi.app
Dockerfile
:
FROM gcr.io/google_appengine/python-compat
ADD . /app
这个 Dockerfile
与 python27 运行 时间使用的相同(实际上是从 gcloud preview app run
生成的 Dockerfile 中复制粘贴的使用 python27 运行 时间),因此这应该与设置 runtime: python27
.
wsgi.py
:
import webapp2
class Hello(webapp2.RequestHandler):
def get(self):
self.response.write(u'Hello')
app = webapp2.WSGIApplication([('/Hello', Hello)], debug=True)
当我在包含这三个文件的目录中 运行 dev_appserver.py app.yaml
时,出现以下错误:
Traceback (most recent call last):
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 83, in <module>
_run_file(__file__, globals())
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/dev_appserver.py", line 79, in _run_file
execfile(_PATHS.script_file(script_name), globals_)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1033, in <module>
main()
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1026, in main
dev_server.start(options)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 818, in start
self._dispatcher.start(options.api_host, apis.port, request_data)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 194, in start
_module.start()
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1555, in start
self._add_instance()
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1707, in _add_instance
expect_ready_request=True)
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/custom_runtime.py", line 73, in new_instance
assert self._runtime_config_getter().custom_config.custom_entrypoint
File "/home/vagrant/google-cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 383, in _get_runtime_config
raise ValueError('The --custom_entrypoint flag must be set for '
ValueError: The --custom_entrypoint flag must be set for custom runtimes
更新
这可能不再准确。查看尼克的回答。
(虽然我做不到,但我并没有很努力)
有一条完全没有记录但绝对必要的信息w.r.t。自定义托管 VM:
它们不能 运行 在开发服务器上!
如果您认为这个重要事实会在任何理智的地方被提及,比如自定义托管 VM 的文档页面,或 dev_appserver.py
,甚至 运行 dev_appserver.py
,那么您给 Google 太多的信任了。
我唯一能找到关于此的任何类型声明的地方是 github 上 appengine-java-vm-guestbook-extras demo 的自述文件(严肃地说):
The Cloud SDK does not support anymore running custom runtimes when a Dockerfile is provided. You'll have to deploy the application to App Engine
Google 不关心:
- 实施这一基本且重要的功能。
- 开发服务器缺少如此重要功能的文档。
- 当用户厌倦执行操作时给出任何合理的错误消息。
我希望这个答案能让一些遗憾的开发人员免于我因此而遭受的折磨。
编辑 1:由 user862857 编辑的解决方案 post 利用 Docker 本身构建图像来自 Docker 文件和 运行 它们在容器中。这也是在开发环境中 运行 管理 VM 和自定义运行时的好方法。
接受的答案似乎不正确。在处理快速发展的 Beta 产品时,github 自述文件的权威性不应胜过 official docs。使用 OP 的 post、
中提到的 Docker 文件,开发环境中的runtime: custom
应用程序是完全可能的
FROM gcr.io/google_appengine/python-compat
ADD . /app
使用 --runtime=python-compat
标志。不过,他们需要捕获对 /_ah/start
和 /_ah/health
的请求。尝试 运行 以下命令,给定以下文件,并亲自查看:
devserver command
$ dev_appserver.py app.yaml --runtime=python-compat
app.yaml
runtime: custom
vm: true
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
Dockerfile
FROM gcr.io/google_appengine/python-compat
RUN apt-get update
RUN apt-get install -y gwhois
ADD . /app
main.py
import logging
import webapp2
from subprocess import Popen, PIPE
class OkHandler (webapp2.RequestHandler):
def get (self):
self.response.write ('ok')
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.headers['Content-Type'] = 'text/plain'
domain = self.request.get ('domain')
cmd = ["gwhois", domain]
process = Popen (cmd, stdout=PIPE, stderr=PIPE)
output, err = process.communicate()
exit_code = process.wait()
self.response.write('stdout: %s' % output)
logging.info ('stderr: %s' % err)
app = webapp2.WSGIApplication([
('/', MainPage),
('/_ah/start', OkHandler),
('/_ah/health', OkHandler)
], debug=True)
向 /?domain=whosebug.com
发送请求以查看实际效果。
N.B.
如果他们希望完全脱离 python-compat 运行time 并简单地 deploy/test 通过 python WSGI 应用程序,他们也可以使用 --custom_entrypoint
标志,只要他们有一个命令可以在合适的端口上启动 运行ning 适当的 WSGI 应用程序(这样的命令将是 uwsgi or gunicorn)。
在尝试让我的自定义 VM 更好地与 dev_appserver 一起工作之后 一天的一部分,接受 对此 post 的回答 作为 非常不愉快的惊喜。但我认为部署开发服务器不会那么那么麻烦,因为毕竟 VM 是标准 Docker 映像。
好吧,确实有一些问题阻止了直接部署的工作。我在下面提供了这些问题的摘要以及我是如何解决它们的。我可能错过了 Docker 和 App Engine 环境之间的一些不兼容性(尤其是我的项目没有使用的 App Engine 的许多方面),但希望它足以让人们起来并 运行ning。
麻烦的来源
首先,我发现 Compute Engine 虚拟机中的 python 环境 运行 是一个
比普通的 VM 环境更宽松(例如 webapp2
之类的包总是可用的)。因此,部署到不太宽容的 Docker
容器环境在我的项目中出现了一些潜在错误。
也就是说,环境存在一些差异 即使您的项目完美无缺,也需要进行一些调整:
问题:gunicorn(或您选择的服务器)必须安装在 Docker 容器的路径。
- 虽然这看起来很明显,但我 运行 遇到了麻烦,因为我包括
gunicorn
在我项目的requirements.txt
文件中。不幸的是,我是 使用只能安装源代码的pip install -t ...
安装所有这些依赖项。结果,图像上没有gunicorn
二进制文件,更不用说PATH
.
- 虽然这看起来很明显,但我 运行 遇到了麻烦,因为我包括
解决方法:显式
pip install gunicorn
- 问题:
google.appengine.*
软件包无法从 App Engine 基础 Docker 图像也无法通过 pip (AFAICT) 获得。- 这可能是一个常见的问题来源,因为
google.appengine.ext.vendor
是将第三方库导入 App Engine 应用程序的推荐接口。
- 这可能是一个常见的问题来源,因为
- 解决方案: 我通过下载整个 Google App Engine 包层次结构并将其放在应用程序的路径上来解决这个问题。
如何获取脚本
用于构建 VM docker 映像并将其部署到 docker 容器的脚本 运行ning 本地可用 here.
有关工作示例,请查看 my project。
如果您有任何评论、功能请求或写得更漂亮,请告诉我 bash 比我高(我觉得我在这方面把门槛定得很低)。