Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Google Cloud App Engine: 502 Bad Gateway (nginx) error with Flask App

I am running a Flask app on Google Cloud App Engine (flex). Running it locally works just fine, but once it deploys I get a 502 Bad Gateway error (nginx). Now I would like to figure out what causes this, but I am not able to find any option to view the console logs that my app creates.

Since it works just fine on my local environment, my current workflow to solve this issue involves changing my code locally and deploying it to see if it works afterwards, but each deployment takes over 30min only to figure out it still does not work. There must be a way to do this more efficiently.

Following the docs https://cloud.google.com/appengine/docs/flexible/python/debugging-an-instance I was able to SSH into my instance in debug-mode and launch the Flask app from the Cloud Shell, however it tells me to access it on http://127.0.0.1:8080/ which I can't access from the cloud server. Hence I can't navigate the webpage in order to reproduce the 502 error and then see the output in the console.

How can I figure out what causes the 502 error on the server?

like image 364
AaronDT Avatar asked May 04 '18 20:05

AaronDT


People also ask

What does 502 bad gateway registered endpoint failed to handle the request?

Webserver overload: If a webserver reaches its limit, it can't answer any more requests — the gateway then delivers the status code 502 Bad Gateway. The reason could be an unexpectedly high interest in the site or even a DDoS attack.


2 Answers

Had the similar issue. Found that app engine looks for app variable in main.py file. My final app.yaml looks like below.

app.yaml

runtime: python
env: flex
entrypoint: gunicorn -b :$PORT main:app

runtime_config:
 python_version: 3

and had requirements.txt, which looks like below.

requirements.txt

Flask==1.1.1
gunicorn==20.0.4
like image 132
radhikesh93 Avatar answered Sep 20 '22 11:09

radhikesh93


Here are my theories:

  • localhost (127.0.0.1) is being used; should use 0.0.0.0
  • Flask internal WSGI server is being used; should use e.g. Gunicorn

NB You may develop and test these solutions using Cloud Shell. Cloud Shell (now) includes a web preview feature that permits browsing endpoints (including :8080) for servers running on the Cloud Shell instance.

Flask

Flask includes a development (WSGI) server and tutorials generally include:

if __name__ == '__main__':
    app.run(host='127.0.0.1', port=8080, debug=True)

Which, if run as python somefile.py will use Flask's inbuilt (dev) server and expose it on localhost (127.0.0.1).

This is inaccessible from other machines:

 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 244-629-469

If instead, host='0.0.0.0' is used, then this will work:

 * Serving Flask app "main" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://0.0.0.0:8080/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 244-629-469
192.168.9.1 - - [08/May/2019 23:59:59] "GET / HTTP/1.1" 200 -
192.168.9.1 - - [08/May/2019 23:59:59] "GET /favicon.ico HTTP/1.1" 404 -

E.g. Gunicorn

Flask's inbuilt server should not be used and Flex's documentation describes how to use gunicorn (one of various alternatives) should be configured:

https://cloud.google.com/appengine/docs/flexible/python/runtime#application_startup

Which, if run gunicorn --bind=0.0.0.0:8080 main:app gives:

[INFO] Starting gunicorn 19.9.0
[INFO] Listening at: http://0.0.0.0:8080 (1)
[INFO] Using worker: sync
[INFO] Booting worker with pid: 7

App Engine Flex

Using the recommended configuration, app.yaml would include:

runtime: python
env: flex
entrypoint: gunicorn --bind:$PORT main:app

Dockerfiles

You can test these locally with Dockerfiles and -- if you wish -- deploy these to Flex as custom runtimes (after revising app.yaml):

FROM python:3.7-alpine

WORKDIR /app
ADD . .

RUN pip install -r requirements.txt

For Flask add:

ENTRYPOINT ["python","main.py"]

NB In the above, the configuration results from the somefile.py app.run(...)

And for gunicorn:

ENTRYPOINT ["gunicorn","--bind=0.0.0.0:8080","main:app"]
like image 20
DazWilkin Avatar answered Sep 16 '22 11:09

DazWilkin