5

I configured a Dart Managed VM for AppEngine like described on the tutorial. It is outdated and still uses the now removed gcloud preview app run instead of dev_appserver.py. I found other people using the dev_appserver.py succesfully for Dart VMs however, but I get the following error:

$ dev_appserver.py app.yaml --runtime custom
INFO     2015-12-11 12:19:50,907 application_configuration.py:431] No version specified. Generated version id: 20151211t121950
INFO     2015-12-11 12:19:50,908 devappserver2.py:769] Skipping SDK update check.
INFO     2015-12-11 12:19:50,939 api_server.py:205] Starting API server at: http://localhost:36858
INFO     2015-12-11 12:19:50,951 api_server.py:648] Applying all pending transactions and saving the datastore
INFO     2015-12-11 12:19:50,951 api_server.py:651] Saving search indexes
Traceback (most recent call last):
  File "/opt/google/cloud-sdk/platform/google_appengine/dev_appserver.py", line 83, in <module>
    _run_file(__file__, globals())
  File "/opt/google/cloud-sdk/platform/google_appengine/dev_appserver.py", line 79, in _run_file
    execfile(_PATHS.script_file(script_name), globals_)
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1040, in <module>
    main()
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 1033, in main
    dev_server.start(options)
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/devappserver2.py", line 824, in start
    self._dispatcher.start(options.api_host, apis.port, request_data)
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/dispatcher.py", line 194, in start
    _module.start()
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1548, in start
    self._add_instance()
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/module.py", line 1700, in _add_instance
    expect_ready_request=True)
  File "/opt/google/cloud-sdk/platform/google_appengine/google/appengine/tools/devappserver2/custom_runtime.py", line 83, in new_instance
    assert self._runtime_config_getter().custom_config.custom_entrypoint
AssertionError

My Dockerfile is in place and app.yaml is correct. I created a sample Dart AppEngine project in IntelliJ and checked the contents of the created files with the tutorial.

This post from the e-mail list suggest to use the --custom_entrypoint option. I tried that, but got this error message. It seems like the port is being claimed by the appserver before the Dart entrypoint is called.

$ dev_appserver.py app.yaml --custom_entrypoint "dart bin/server.dart --port=8080"
INFO     2015-12-11 12:41:13,334 application_configuration.py:431] No version specified. Generated version id: 20151211t124113
INFO     2015-12-11 12:41:13,334 devappserver2.py:769] Skipping SDK update check.
INFO     2015-12-11 12:41:13,363 api_server.py:205] Starting API server at: http://localhost:44617
INFO     2015-12-11 12:41:13,375 dispatcher.py:197] Starting module "default" running at: http://localhost:8080
INFO     2015-12-11 12:41:13,376 admin_server.py:116] Starting admin server at: http://localhost:8000
Unhandled exception:
SocketException: Failed to create server socket (OS Error: Address already in use, errno = 98), address = 0.0.0.0, port = 8080
#0      _NativeSocket.bind.<anonymous closure> (dart:io-patch/socket_patch.dart:494)
#1      _rootRunUnary (dart:async/zone.dart:914)
#2      _CustomZone.runUnary (dart:async/zone.dart:810)
#3      _Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:502)
#4      _Future._propagateToListeners (dart:async/future_impl.dart:585)
#5      _Future._completeWithValue (dart:async/future_impl.dart:376)
#6      _Future._asyncComplete.<anonymous closure> (dart:async/future_impl.dart:430)
#7      _rootRun (dart:async/zone.dart:907)
#8      _CustomZone.run (dart:async/zone.dart:802)
#9      _CustomZone.bindCallback.<anonymous closure> (dart:async/zone.dart:735)
#10     _microtaskLoop (dart:async/schedule_microtask.dart:43)
#11     _microtaskLoopEntry (dart:async/schedule_microtask.dart:52)
#12     _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:96)
#13     _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:151)
^CTraceback (most recent call last):
  File "/opt/google/cloud-sdk/bin/dev_appserver.py", line 35, in <module>
    main()
  File "/opt/google/cloud-sdk/bin/dev_appserver.py", line 29, in main
    os.path.join('platform', 'google_appengine'), 'dev_appserver.py', *args)
  File "/opt/google/cloud-sdk/bin/bootstrapping/bootstrapping.py", line 45, in ExecutePythonTool
    execution_utils.ArgsForPythonTool(_FullPath(tool_dir, exec_name), *args))
  File "/opt/google/cloud-sdk/bin/bootstrapping/bootstrapping.py", line 86, in _ExecuteTool
    execution_utils.Exec(args + sys.argv[1:], env=_GetToolEnv())
  File "/opt/google/cloud-sdk/lib/googlecloudsdk/core/execution_utils.py", line 209, in Exec
INFO     2015-12-11 12:41:37,298 shutdown.py:45] Shutting down.
    ret_val = p.wait()
  File "/usr/lib64/python2.7/subprocess.py", line 1384, in wait
INFO     2015-12-11 12:41:37,298 api_server.py:648] Applying all pending transactions and saving the datastore
    pid, sts = _eintr_retry_call(os.waitpid, self.pid, 0)
  File "/usr/lib64/python2.7/subprocess.py", line 476, in _eintr_retry_call
    return func(*args)
KeyboardInterruptINFO     2015-12-11 12:41:37,298 api_server.py:651] Saving search indexes
Steven Roose
  • 2,731
  • 4
  • 29
  • 46
  • How does your app.yaml look like? Do you pass the custom_runtime flag? https://groups.google.com/a/dartlang.org/forum/#!msg/cloud/J6LsrVVdJ6o/WTHbG_v0CQAJ – Günter Zöchbauer Dec 11 '15 at 13:53
  • I don't have the app.yaml with me right now, but it is the default `runtime: custom, vm: true, api_version: 1`. I also tried the `--custom_entrypoint` option, but that failed because the `dev_appserver` already claimed port 8080 (something with a default module) so that Dart could not use it. I will add error logs for that asap, I'm on a different machine right now. – Steven Roose Dec 11 '15 at 14:54
  • @GünterZöchbauer I added the error message for your suggested method. – Steven Roose Dec 11 '15 at 15:38
  • I haven't used it for quite a while myself. Maybe someone else has an idea. – Günter Zöchbauer Dec 11 '15 at 15:52
  • Can you run `sudo netstat -plant` to determine whether anything else is running on 8080? – Nick Dec 11 '15 at 16:40

2 Answers2

1

The tutorial is outdated and you can no longer do this.

The reason why is that you are using a custom runtime (the app.yaml in the tutorial has runtime: custom).

Custom runtimes can no longer be run on the development server!!! (see this answer)

It is possible to run the app, but you will have to deploy to App Engine servers.

Community
  • 1
  • 1
user2771609
  • 1,867
  • 1
  • 15
  • 36
  • This is incorrect, and [a correct answer](http://stackoverflow.com/a/34279138/4270992) has just been posted to the Q&A you linked. Generally, it's not right to trust a one-off comment in a README over the [official docs](https://cloud.google.com/appengine/docs/managed-vms/custom-runtimes). – Nick Dec 15 '15 at 00:38
  • What would be helpful is if the official docs said something (anything, anything at all) about how to run a custom runtime dev_appengine.py. Also the --runtime flag seems new. I cannot find it in 1.9.28. – user2771609 Dec 15 '15 at 00:56
0

I think the correct thing to do here would be to specify a custom entrypoint which runs your dart server application, since --runtime is only for specific supported compatible runtimes. See the error output from dev_appserver.py:

google.appengine.tools.devappserver2.errors.InvalidAppConfigError: 
Must set either --runtime or --custom_entrypoint.  
For a standard runtime, set the --runtime flag with one of 
['java-compat', 'java', 'php55', 'python', 'custom', 
'python-compat', 'java7', 'python27', 'go'].  
For a custom runtime, set the --custom_entrypoint with a command to start your app.
Nick
  • 3,581
  • 1
  • 14
  • 36
  • Can you elaborate on what --custom_entrypoint does? dev_appserver.py --help simply paraphrases the term: "specify an entrypoint for custom runtime modules". What does an entrypoint mean? Is it a file? Is it a program? Is it a program in the docker container? The machine running dev_appserver.py? What should the program do? – user2771609 Dec 15 '15 at 01:00
  • It's exactly as it sounds, a command which spawns a process listening on the appropriate port, such as `node server.js`, or `gunicorn -b localhost:{port} mymodule:application` (the second one shows the use of {port} as a template in the command which will be filled with the appropriate value before being run). – Nick Dec 15 '15 at 22:55
  • And what should the process do after attaching to the port? How does this process relate to the docker image specified by my Dockerfile? Am I supposed to start the docker container to implement this process? – user2771609 Dec 16 '15 at 00:23
  • As `node server.js` suggests, what should happen is that the process will listen for HTTP requests on that port and send responses. Note that this is just one way of running your code. You could simply run the node/dart server itself, and you could also, as you hinted at just now, build an image from your Dockerfile and run it in a container. The latter would be the most accurate approximation of the production environment. – Nick Dec 16 '15 at 00:28
  • Ahhhhhhhhh! So it should implement the module!!! It is a process that implements the module! This is not at all what "entrypoint" means if you ask me. How does this work with multiple modules though? – user2771609 Dec 16 '15 at 00:33