Search code examples
pythonamazon-web-servicesamazon-elastic-beanstalktornado

Deploying Tornado app on AWS Elastic Beanstalk


I have a server written in Python 2.7/Tornado and I am trying to deploy it on AWS. I came across AWS Elastic Beanstalk which looked like a very convenient method to deploy my code.

I went through this tutorial and was able to deploy the Flask sample app. However, I can't figure out how to deploy a test tornado app like below.

import tornado.web
import tornado.ioloop

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

if __name__ == "__main__":
    app = tornado.web.Application([
        (r"/.*", MainHandler),
    ])

    app.listen(5000)
    tornado.ioloop.IOLoop.current().start()

All my requests result in an Error 500 when I try to deploy the above application and I have no idea how to troubleshoot this problem as I have no idea how the Flask sample is working but the Tornado code is not.

The requirements.txt file has an entry for tornado==4.4.2 in it.

I tried adding a few log statements to write to an external file but the file is not being created, which probably means the application does not even start.

It would be great if someone can provide some steps on deploying a Tornado app on AWS-EB or how I should start troubleshooting this. Please let me know if I need to provide any more details.

Thanks!

Update

After noticing the errors in httpd error_log file, AWS Documentation and Berislav Lopac's answer, I found the correct way to implement the Tornado server. Here is a simple server

import tornado.web
import tornado.wsgi
import tornado.ioloop

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

webApp = tornado.web.Application([
    (r"/", MainHandler),
])

# Wrapping the Tornado Application into a WSGI interface
# As per AWS EB requirements, the WSGI interface must be named
# 'application' only
application = tornado.wsgi.WSGIAdapter(webApp)

if __name__ == '__main__':
    # If testing the server locally, start on the specific port
    webApp.listen(8080)
    tornado.ioloop.IOLoop.current().start()

Additional Links: Tornado WSGI Documentation


Solution

  • I believe your issue is related to the fact that Elastic Beanstalk uses WSGI for serving Python Web apps, while Tornado's server is not WSGI-compliant. You might want to try wrapping your app in the WSGI adapter before serving it via WSGI.

    This should work fine unless you rely on Tornado's asynchronous capabilities, as WSGI is strictly synchronous.