Cannot run Google App Engine custom managed VM: --custom-entrypoint must be set error

China☆狼群 提交于 2019-11-30 04:06:00

UPDATE

THIS MAY NO LONGER BE ACCURATE. SEE NICK'S ANSWER.

(Though I could not get that working. But I did not try very hard)


There is a completely undocumented but absolutely essential piece of information w.r.t. custom managed VMs:

THEY CANNOT BE RUN ON THE DEVELOPMENT SERVER!

If you think this crucial fact would be mentioned anywhere sane, like say, the documentation page for custom managed VMs, or for dev_appserver.py, or even as an error message when running dev_appserver.py, then you are giving Google far too much credit.

The only place where I can find any kind of statement about this is in the Readme file of the appengine-java-vm-guestbook-extras demo on github (seriously):

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 does not care to:

  1. Implement this basic and important feature.
  2. Document that the development server is missing such an important feature.
  3. Give any reasonable error message when the user tires to perform the action.

I hope this answer saves some sorry developer from the days of torment I suffered because of this.

EDIT 1: The solution posted by user862857 makes use of Docker itself to build images from the Dockerfile and run them in containers. This is also a good approach to running Managed VMs and Custom Runtimes in development contexts.


The accepted answer doesn't seem correct. A github README should not trump the official docs for authoritativeness when dealing with a rapidly-evolving Beta product. It's perfectly possible to a runtime: custom app in the dev environment, using the Dockerfile mentioned in OP's post,

FROM gcr.io/google_appengine/python-compat
ADD . /app

using the --runtime=python-compat flag. They would need to catch requests to /_ah/start and /_ah/health, though. Attempt to run the following command, given the following files, and see for yourself:

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)

Send a request to /?domain=stackoverflow.com to see this in action.


N.B.

If they wished to entirely decouple from the python-compat runtime and simply deploy/test a python WSGI app via, they could also use the --custom_entrypoint flag, so long as they had a command which would start running the appropriate WSGI app on a suitable port (such a command would be uwsgi or gunicorn).

user862857

After trying to get my custom VM working with dev_appserver for the better part of a day, the accepted answer to this post came as a pretty unpleasant surprise. But I figured deploying a dev server couldn't be that much of a hassle because, after all, the VM is a standard Docker image.

Well there did turn out the be a few issues that prevent a straight deployment from working. I've provided a summary of these issues below as well as how I solved them. I may have missed some incompatibilities between the Docker and App Engine environments (especially with the many aspects of App Engine that my project didn't use) but hopefully it's enough to get people up and running.

Sources of trouble

First, I found the python environment run in the Compute Engine VMs to be a bit more lenient than a normal VM environment (e.g. packages like webapp2 are always available). Consequently, deploying to the less forgiving Docker container environment surfaced some latent errors in my project.

That being said, there are some differences in the environments that necessitate some tweaks even if your project is flawless:

  • Problem: gunicorn (or the server of your choice) must be installed on the Docker container's path.

    • While this may seem obvious, I ran into trouble because I included gunicorn in my project's requirements.txt file. Unfortunately, I was installing all of these dependencies using pip install -t ... which is only able to install source. As a result, there was no gunicorn binary on the image let alone on the PATH.
  • Solution: Explicitly pip install gunicorn


  • Problem: google.appengine.* packages are not available from the App Engine base Docker image nor are they available via pip (AFAICT).
    • This may be a common source of trouble because google.appengine.ext.vendor is the recommended interface for importing third-party libraries into your App Engine app.
  • Solution: I got around this by downloading the entire Google App Engine package hierarchy and placing it on the path of the app.

How to get the script

The script to build and deploy the VM docker image to a docker container running locally is available here.

For an working example, check out my project.

Let me know if you have a comment, a feature request, or if you write prettier bash than me (I feel I've set the bar comfortably low on that count).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!