falcon icon indicating copy to clipboard operation
falcon copied to clipboard

Expand deployment guide

Open kgriffs opened this issue 9 years ago • 11 comments

Discuss deployments using some of the more popular web servers and cloud providers. This guide should only provide high-level guidance, and defer to the relevant project/vendor docs for details.

WSGI servers

  • uWSGI
  • Gunicorn
  • httpd

Short discussion on reverse proxies, load balancers:

  • HAProxy
  • Nginx
  • httpd
  • lighttpd
  • Appliances (e.g., F5)
  • IaaS (e.g., ELB, Google Cloud LB)

Cloud providers:

  • AWS
  • Google
  • Microsoft
  • Digital Ocean
  • Heroku

See also:

  • http://bottlepy.org/docs/dev/deployment.html
  • http://werkzeug.pocoo.org/docs/0.11/deployment/
  • https://redmine.lighttpd.net/projects/lighttpd2/wiki/Howto_WSGI

kgriffs avatar Mar 06 '15 21:03 kgriffs

@kgriffs can I take this on me?

anekix avatar Aug 24 '17 03:08 anekix

@anekix go for it, thanks!

kgriffs avatar Aug 24 '17 16:08 kgriffs

Hi @anekix, just following up, were you still interested in taking this one?

kgriffs avatar Sep 30 '17 00:09 kgriffs

OK, I'm assuming this one is fair game for anyone else who would like to pick it up. :)

kgriffs avatar Oct 13 '17 23:10 kgriffs

I have some examples of working with uWSGI & NGINX. What would be most helpful? An example configuration file and maybe a wsgi.py file for how to attach an app to an uWSGI master?

nZac avatar Oct 14 '17 23:10 nZac

Related: https://github.com/falconry/falcon/issues/899

kgriffs avatar May 12 '18 21:05 kgriffs

@nZac I think it would be great to have a page added to the doc with sections for difference deployment scenarious and a TOC at the top. uwsgi + nginx would be a great first addition to that page.

kgriffs avatar May 12 '18 21:05 kgriffs

For Gunicorn, you can reference the official Deploying Gunicorn docs which I found very helpful recently.

I think it would be good to make a recommendation on which workers are recommended. In my testing of a little hello world app, meinheld workers performed the best with Falcon.

           falcon (req/sec)
--------- ------------------
eventlet        19.94k 
gevent          19.95k
gunicorn        13.28k
meinheld        70.62k
uwsgi           errors

I would really like to see some recommendations on uWSGI settings too as I would constantly see socket errors when smashing uWSGI with load.

Tested on the following instance:

AMI: CentOS 7 (x86_64) - with Updates HVM
Type: t2.2xlarge
vCPUs: 8
Memory (GiB): 32
Python: 3.6.5 (from IUS YUM repository)

With the following test command:

wrk --duration 10s --threads 1 --connections 200 http://wsgi:8000

And the following Gunicorn command:

gunicorn \
  --workers 17 --worker-class=meinheld.gmeinheld.MeinheldWorker \
  --bind 0.0.0.0:8000 \
  hello_falcon:app

And finally here's the Falcon code:

import falcon

class HelloResource(object):
    def on_get(self, req, resp):
        resp.body = 'Hello World!'

app = falcon.API()
app.add_route('/', HelloResource())

To be honest, in all my testing thus far, I'm just not convinced of PyPy's performance once you add the WSGI server in, hence my issue #1309 so I'm keen to see your suggestions on deploying with PyPy too 😄

Keep up the great work! Fotis

fgimian avatar May 22 '18 00:05 fgimian

Hope it's OK if I post another little tip I've learned here. If you are deploying with Gunicorn, it's important that you configure logging to write to Gunicorn's error logger or it won't log correctly during deployment.

To make this easy, I add the handler to the root logger like so:

# Configure the root handler log level and ensure that it is set to send logs
# to Gunicorn's error logs.
gunicorn_error_logger = logging.getLogger('gunicorn.error')
logging.root.handlers.extend(gunicorn_error_logger.handlers)
logging.root.setLevel(gunicorn_error_logger.level)

Perhaps the suggestion could then be that resources simply inherit this log level:

...
        self.logger = logging.getLogger('app.endpoint')
        self.logger.setLevel(logging.root.level)
...

Or of course, they can override it.

Hope this helps Fotis

fgimian avatar May 23 '18 07:05 fgimian

I find the gunicorn + meinheld deployment very easy to set-up @see https://github.com/the-benchmarker/web-frameworks/blob/master/python/falcon/Dockerfile#L12

waghanza avatar Mar 11 '19 12:03 waghanza

Hi @fgimian, did you managed to have PYPY to work with Falcon + Gunicorn?

B1gG avatar Mar 11 '21 17:03 B1gG