0

I'm attempting to access Firestore from within an AWS Elastic Beanstalk deployment. The EB application is written using Flask in Python, and everything works correctly locally. But, when I try to deploy to EB, only the first database request succeeds-- the second one freezes my application during the call to .get().

I'm not sure if this is a permissions thing on EB, a Firestore issue, or what! Since no exception is thrown, I can't even deny the request and move on.

I do get the following in the logs:

[Tue Jun 26 11:29:16.964989 2018] [core:error] [pid 3914] [client 172.31.17.165:22711] Script timed out before returning headers: application.py

... but that's because the script is timing out due to the call to .get() never returning.

Here's my full code for this test app:

import os

from flask import Flask, url_for, redirect, render_template
import mimetypes
import time

import google
import firebase_admin
from firebase_admin import credentials
from firebase_admin import firestore

print("=====================================================")
print("initializing app")
cred = credentials.Certificate("/my/actual/path/to/credentials/is/here.json")
firebase_admin.initialize_app(cred)
print("done.")

print("initializing firestore")
db = firestore.client()
print("done.")

print("initializing flask")
application = Flask(__name__)
print("done.")

@application.route('/doc/<docId>')
def doc(docId):
    docId = docId.lower()

    documents_ref = db.collection(u'documents')
    doc_ref = documents_ref.document(docId)

    print("getting doc")
    doc = None
    try:
        doc = doc_ref.get()
    except google.cloud.exceptions.NotFound:
        print("not found.")
        return render_template('doc.html', message="This document no longer exists .")
    print("done.")

    # Here is where I'd normally use the DB snapshot data, but omitted for the question
    creatorStr = "Someone"
    timeStr = "a time"

    docMessage = creatorStr + " sent you a document dated " + timeStr + "."

    return render_template('doc.html', docMessage=docMessage)

if __name__ == "__main__":
    # application.debug = True
    application.run()

Any help would be greatly appreciated!

CapnPhoton
  • 33
  • 5
  • Beanstalk logs might give you an indication as to what the problem is. Through the console, you can download the full bundle logs and see if there's something obvious in it. Through the EBCLI, you can perform `eb logs` against the same. If there's no indication in the logs, I would recommend SSH-ing into the beanstalk instance and running the application manually there. I think you should find the application under `/var/lib/current`. – progfan Jun 26 '18 at 19:13
  • The logs don't show anything of interest, it seems... the last message in the error log is "getting doc" from the script, then nothing until it times out. – CapnPhoton Jun 27 '18 at 09:37
  • I'm trying to figure out how to SSH into the instance to run it manually... I think the python app is in `/opt/python/current`, and I can launch it with `flask run`, but I'm still trying to figure out how to access the instance externally to test things. – CapnPhoton Jun 27 '18 at 09:39
  • Okay, I connected to the instance w/ `eb ssh`, `source /opt/python/current/env`, and `flask run`, and that started the flask server on the instance on port 5000. Then, I tested it with `curl http://127.0.0.1:5000/doc/test` and it seems to work every time there. So it doesn't seem to be the instance accessing the outside world that's the problem? Or, there's something different when EB runs the flask server vs. when I do? – CapnPhoton Jun 27 '18 at 09:44
  • *So it doesn't seem to be the instance accessing the outside world that's the problem?* -- might very well be the case. Can you determine if the EC2 instance associated with the environment is allowing incoming traffic on 5000 through its security group? Can you tell me what kind of a load balancer your environment is using? – progfan Jun 27 '18 at 17:42
  • I'm using a classic load balancer, and everything is communicating well with the flask server, except for the call to `.get()` which freezes the instance. If I don't make the call to `.get()`, the rest of the web app continues to work as expected. – CapnPhoton Jun 29 '18 at 16:02
  • I'm running into this exact issue as well. Did you ever find a solution? – Joel Green Aug 16 '19 at 03:02

1 Answers1

0

Ok I finally found the solution to the issue it was here: AWS Elastic Beanstalk - Script timed out before returning headers: application.py

Create an ebextension file like so and redeploy to fix the issue:

nano .ebextensions/<some_name>.config 

#add the following to <some_name>.config 
files:
  "/etc/httpd/conf.d/wsgi_custom.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      WSGIApplicationGroup %{GLOBAL}


#add to git
git add .ebextensions/<some_name>.config
git commit -m 'message here'

#deploy to beanstalk
eb deploy
Joel Green
  • 920
  • 9
  • 18