Gunicorn

Hace no mucho que empecé a escuchar sobre Gunicorn, creo que allá por Marzo cuando Lorenzo Gil se encontraba en la PyCon 2011, pero no me había propuesto probarlo hasta hace unos días. Pero bueno, empecemos por el principio...

¿Qué es Gunicorn?

Gunicorn, también conocido como Green Unicorn (Unicornio Verde), es un servidor WSGI HTTP para Python. Es un pre-fork del proyecto Unicorn de Ruby. Gunicorn es compatible con varios web frameworks, soporta WSGI, Django y Paster de forma nativa; consume pocos recursos en ejecución y es bastante rápido.

Como he comentado en el párrafo anterior, soporta nativamente WSGI, Django y Paster; administra los workers de forma automática, permite establecer hooks para hacerlo más extensible, compatible con Python 2.5 o superior.

Instalando Gunicorn

Su instalación es realmente sencilla, justo como cualquier otro módulo de Python.
$ pip install gunicorn

o si lo preferimos, podemos obtener el código con git e instalarlo como cualquier otra aplicación en Python.

$ git clone git://github.com/benoitc/gunicorn.git
$ cd gunicorn
$ python setup.py install

Una vez instalado Gunicorn tendremos a nuestra disposición tres comandos con los que servir diferentes web frameworks.

Ejecutando Gunicorn

Los comandos disponibles en Gunicorn son:
  • gunicorn: utilizado para servir aplicaciones WSGI.
  • gunicorn_django: utilizado para servir aplicaciones Django.
  • gunicorn_paster: para frameworks compatibles con Paster como Pylons, TurboGears 2, ...

En este post me centraré en el comando gunicorn pero podeis encontrar más información de cada uno de ellos en la documentación oficial de Gunicorn.

Configurando Gunicorn

La configuración de Gunicorn también es muy sencilla, básicamente consiste en un fichero Python que tenga permisos de lectura en el sistema de ficheros, excepto que nuestra aplicación haya sido desarrollada utilizando Paster, en este caso haremos uso de un fichero INI.

Su sintaxis de uso es:

$ gunicorn [OPTIONS] APP_MODULE

Donde APP_MODULE está compuesto por $(MODULE_NAME):$(VARIABLE_NAME). Un ejemplo de uso sería el siguiente:

$ gunicorn --workers 2 prueba:aplicacion

Gunicorn buscará el módulo, es decir, el fichero prueba.py, y el nombre de la variable (aplicacion) debe hacer referencia a una función, normalmente a la función main de nuestra aplicación, que debe encontrarse especificada en el módulo.

El comando gunicorn ofrece una extensa lista de opciones para configurar su comportamiento, pero las que he utilizado y que me han parecido más interesantes son:

  • --config FILE: ruta hacia el fichero de configuración.
  • --bind ADDRESS: es posible especificar tanto HOST:PUERTO como la ruta a un socket con unix:RUTA_SOCKET. Ejemplo: --bind unix:///home/mviera/gunicorn/gunicorn.sock
  • --workers INT: número de procesos workers que se arrancarán para servir las peticiones.
  • --max-requests INT: número máximo de peticiones que servirá un worker antes de ser reiniciado.
  • --debug: activa el debug en el servidor.
  • --log-file: fichero de log.

Un ejemplo de ejecución sería:

$ gunicorn modulo:application --workers 2 \
--bind unix:///home/mviera/gunicorn/gunicorn.sock \
--max-requets 1000 --log-file /home/mviera/gunicorn/gunicorn.log

Podeis consultar el resto de opciones en la documentación de configuración de Gunicorn.

Por último y para terminar con el despliegue, una vez que tengamos a Gunicorn sirviendo nuestra aplicación lo correcto sería instalar un servidor web que actúe como proxy HTTP hacia nuestra aplicación, yo como siempre recomiendo utilizar Nginx :-)

Y hasta aquí lo que he aprendido sobre Gunicorn, un breve resumen de la documentación oficial.

Conclusiones

Gunicorn me ha sorprendido no solo por su fácil instalación, a diferencia de uWSGI que necesita ser compilado; sino también por su fácil configuración y uso.

Como dije al principio, cuenta con una serie de hooks que permite ejecutar código Python en los diferentes puntos de ejecución: on_start, when_ready, on_reload, pre_fork, post_fork, etc. Esto también me ha gustado mucho, aunque no los he llegado a probar.

La verdad es que Gunicorn me ha dejado con un muy buen sabor de boca aunque no he llegado a probarlo en un entorno real de producción para ver cómo se comporta. De momento seguiré con uWSGI hasta que tenga la ocasión de utilizar Gunicorn ;-)

Un saludo.

PD: En el próximo post explicaré cómo desplegar Trac utilizando Gunicorn!