Usar Virtualenv en Producción con Apache y Mod WSGI

Usar Virtualenv en Producción con Apache y Mod WSGI

Si desarrollas en Python, es normal que con cada nuevo proyecto que comiences actualices las librerías o paquetes instalados en tu sistema, ya sea para estar al día con versiones actuales y estables, o para probar nuevas funcionalidades. Una de las malas practicas que adquirimos los desarrolladores en nuestros inicios es instalar todas las librerías de forma global y mantener un mismo entorno de trabajo para todos los proyectos. Actualizamos, borramos e instalamos nuevas librerías con frecuencia, siempre pensando en nuestro proyecto actual y sin darnos cuenta que esto va a producirnos dolores de cabeza a futuro.

Entre tanto ir y venir de actualizaciones y paquetes seguramente rompamos las dependencias de alguna aplicación desarrollada anteriormente y en funcionamiento. ¡Ahí es cuando empiezan los problemas!.

Si intentamos correr un proyecto viejo es muy probable que nos choquemos de frente con un sinfín de incompatibilidades entre nuestro código y las librerías actuales.
Me ha pasado de encontrarme trabajando con Django v1.9 y tener que correr un proyecto desarrollado para v1.6. El resultado: ¡Errores por todos lados!

Virtualenv es la herramienta que viene a darnos una solución, ya que nos permite crear entornos de Python aislados uno de otro, cada uno con sus propias librerías. Por ejemplo, podemos tener un entorno con Python 2.7 y Django 1.6 para esa web vieja que tienes que tocar de vez en cuando, y un entorno con Python 3.5 para ese proyecto que te encuentras migrando actualmente.

Virtualenv

Lo mas interesante es que podemos configurar virtualenv para usarlo en producción con Apache + mod_wsgi y así desplegar varios proyectos con distintas dependencias en el mismo servidor.

Primero, vamos a aprender un poco sobre el uso de virtualenv.

Instalar Virtualenv

Vamos a instalar virtualenv usando pip, el manejador de paquetes de Python. Si no lo tienes, simplemente descarga el archivo get-pip.py y en tu consola corre el comando python get-pip.py.

Para instalar virtualenv abrimos la terminal e ingresamos el siguiente comando:

$ pip install virtualenv

Nota: Si estas en Linux / OS X recuerda correr el comando con sudo para evitar problemas de privilegios.

Como crear nuestro primer entorno virtual

Con unos pocos comandos ya estaremos trabajando de manera correcta, con entornos aislados para cada uno de nuestros proyectos y sin miedo a meter la pata cada vez que actualizamos alguna librería.

Lo primero será decidir como vamos a organizar los entornos virtuales. En mi caso opte por crearlos en el directorio root de cada uno de mis proyectos, pero también podrías tener un único directorio donde almacenarlos a todos.

Una vez lo tengas decidido, vamos nuevamente a la consola y creamos el entorno de esta forma:

$ virtualenv myenv

Donde myenv va a ser el directorio que contendrá todos los archivos de nuestro entorno virtual.

Como crear un virtualenv

Por defecto virtualenv instala los paquetes setuptools, pip y wheel; y nos informa la ubicación del ejecutable de Python.

El directorio del entorno virtual tiene el siguiente árbol de carpetas:

myenv/
    bin/
    include/
    lib/
    local/
    pip-selfcheck.json

El interprete de Python que se creara con nuestro entorno virtual es el mismo con el que fue instalado virtualenv. Sin embargo puede que necesites crear un entorno con otro interprete, como Python 3.5 por ejemplo. Lo podemos hacer de la siguiente manera:

$ virtualenv -p path/to/python3.5 myenv

Para usar el entorno que acabamos de crear, y así poder instalar los paquetes que nuestro proyecto necesita es necesario activarlo:

$ source myenv/bin/activate

En el prompt de nuestra consola se mostrara el nombre del entorno activo para indicarnos que estamos trabajando en un entorno activo, tal como se puede ver en la imagen:

Entorno activo

A partir de este momento, cada paquete que instalemos estará disponible únicamente dentro del entorno virtual, independiente de cualquier otro entorno y de la configuración global de nuestro sistema.

Para desactivar el entorno activo simplemente salimos de la consola o ejecutamos el comando deactivate:

(myenv) $ deactivate

Borrar un entorno virtual

Si necesitamos borrar un entorno virtual simplemente eliminamos el directorio:

$ rm -r myenv



Lo visto hasta el momento es totalmente aplicable para crear entornos virtuales en nuestra maquina local (para desarrollo) o en un servidor de producción. En la siguiente sección aprenderemos a configurar virtualenv en un servidor con Apache y mod_wsgi corriendo sobre un VPS Linux. Si tu servidor no es Linux ¿que estas esperando para conseguir uno?

Usar Virtualenv en producción con Apache y mod_wsgi

mod_wsgi es un modulo para Apache que implementa una interfaz compatible con WSGI (Web Server Gateway Interface) para servir aplicaciones web desarrolladas en Python. En el mundo Python, WSGI ya es casi un estándar y la mayoría de los frameworks web actuales lo soportan: Django, Flask, Pyramid, web2py, CherryPy, Bottle, Falcon, entre otros.

Podes instalarlo de dos maneras, con apt-get:

$ sudo apt-get install libapache2-mod-wsgi

O puedes optar por realizar la instalación desde el código fuente que es explicada paso a paso en la documentación.

Una vez instalado será necesario habilitar el modulo y reiniciar Apache para poder hacer uso de él:

$ sudo a2enmod wsgi
$ sudo service apache2 restart

Ahora vamos a crear el entorno virtual en el servidor, nos situamos en el directorio del proyecto, o donde vayas a mantener tus entornos, y lo creamos con el comando visto anteriormente:

$ virtualenv myenv

¡Ya es momento de configurar Apache! Vamos a editar el archivo virtual host de nuestro sitio y añadir la directiva WSGIDaemonProcess para decirle a Apache que ejecute el proceso WSGI en modo daemon. En esa misma directiva le vamos a indicar dos rutas, la de nuestro proyecto y la del directorio de librerías del entorno virtual, separadas por :.

WSGIDaemonProcess mysite python-path=/path/to/mysite:/path/to/mysite/myenv/lib/pythonX.X/site-packages

mysite es el nombre que le damos al proceso WSGI, puede contener el nombre que creamos conveniente.

Debajo vamos a agregar las directivas WSGIProcessGroup y WSGIScriptAlias. Con la primera indicamos que el proceso corre en el grupo mysite (debe tener el mismo nombre que el indicado en WSGIDaemonProcess), y con la segunda indicamos el archivo que contiene la configuración WSGI a la que se debe dirigir Apache cuando reciba una solicitud en la raíz del dominio (esto se indica con el primer slash /).

WSGIProcessGroup mysite
WSGIScriptAlias / /path/to/mysite/wsgi.py

La configuración y ruta del archivo WSGI dependerá del framework que estés utilizando.

Por ultimo, volvemos a reiniciar Apache para que tome la nueva configuración:

$ sudo service apache2 restart

De esta forma logramos configurar nuestra aplicación Python para que corra en su propio entorno virtual, y podemos hacer exactamente lo mismo con los demás desarrollos que tengamos, permitiéndonos utilizar el mismo servidor para hostear todos los proyectos.

Si te sientes mas identificado con Nginx para utilizar como servidor web, aquí puedes ver como configurar Nginx con uWSGI en reemplazo a Apache y mod_wsgi.



Si VPS, Apache, virtual host y servidor web te suena a chino te recomiendo darle una leida a mi post anterior donde hablo un poco sobre estos conceptos. Y cualquier duda que tengas puede dejarla en los comentarios o escribirme a hola@luciano.im.

comments powered by Disqus