06Nov

Cómo ejecutar una aplicación Flask con el servidor WSGI HTTP Gunicorn

Guía para configurar una aplicación Flask para entornos de producción con el servidor WSGI Gunicorn.

¿Qué es Gunicorn?

Gunicorn es un servidor HTTP para sistemas Unix que cumple la especificación WSGI. Nos permite servir nuestra aplicación Flask con múltiples workers para incrementar el rendimiento de nuestra aplicación.

Es recomendable para entornos de producción no usar el servidor web integrado en Flask, que tiene como objetivo un entorno de desarrollo.

La aplicación Flask

La aplicación Flask de ejemplo que vamos a usar para ejecutar con Gunicorn se puede descargar del repositorio de Github urodoz/sample-flask-gunicorn-configuration donde está todo el código usado en este artículo.

El archivo servidor, server.py, que está dentro de la carpeta sample contiene la declaración del objeto Server.

A continuación tenemos la estructura de archivos usada para el ejemplo:

sample/
    __init__.py
    server.py
wsgi.py

Examinando el contenido del archivo de servidor, observamos que tiene una única ruta en «/» que devuelve una respuesta JSON:

from flask import Flask, jsonify


class Server(object):
    
    app = None

    def __init__(self):
        self.app = Flask(__name__)
        self.app.secret_key = '7q%3=;8J+X5:f.+pU9e!;6x:E*n_9^Ky0~.R'

        @self.app.route('/')
        def home():
            return jsonify({
                "ping": "pong"
            })

A continuación tenemos el contenido del archivo wsgi.py, contiene un constructor del objeto de aplicación, clase Server y un wrap con ProxyFix de la librería werkzeug.

Este wrap hace uso de las cabeceras X-Forwarded para que sean detectadas correctamente por la aplicación sobre Flask dentro de las variables internas REMOTE_ADDR y HTTP_HOST si estamos detrás de un proxy. De otra forma tendríamos que gestionarlo manualmente en nuestra aplicación.

from sample.server import Server

new_server = Server()
app = new_server.app

from werkzeug.contrib.fixers import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

El archivo wsgi.py solo crea una nueva instancia del servidor de ejemplo y expone la variable app, la aplicación Flask.

Ejecutando wsgi.py con Gunicorn

Para ejecutar este pequeño servidor Flask usando el servidor Gunicorn simplemente escribimos el siguiente comando:

gunicorn -w 3 -b 0.0.0.0:3000 wsgi:app

El argumento wsgi:app de la ejecución hace referencia a la aplicación a importar. En este caso es la variable app del paquete wsgi.py.

Hemos ejecutado el servidor Gunicorn con 3 workers, lo hemos definido con el parámetro w, en el ejemplo: -w 3.

Para calcular el número máximo de workers, se puede usar la siguiente fórmula:

from multiprocessing import cpu_count

maximos_workers = cpu_count() * 2 + 1

Si entramos ahora en la dirección http://172.17.0.1:3000 con el proceso de Gunicorn en ejecución podremos ver la respuesta JSON.

Web de Gunicorn: http://gunicorn.org/

Web del framework Flask: http://flask.pocoo.org/

Leave a comment