Skip navigation

Ultimamente he estado revisando muchas cosas respecto a django (hasta la fecha el único framework que no he “mandado a la cresta”), y a pesar de haber ya hecho unos cuantos proyectos que ya están funcionando (laborales) y otros que espero algún día lanzar , siempre he encontrado que el desplegar proyectos es bastante engorroso; sobre todo si tu proyecto depende de muchas aplicaciones externas; el problema es mayor cuando alguien quiere colaborar con tu proyecto, ahi si que entras al maravilloso mundo del “dependency hell” y amigos.

Es así como hace algún tiempo llegue a Buildout; una solución aparentemente orientada a Plone, pero que es genérica y fácilmente utilizable con cualquier proyecto python (como Django, mi framework favorito).Para empezar, buildout es un sistema de “construccion” de software/paquetes/asdf que permite especificar las diferentes “partes” que componen un proyecto, como dependencias (python o no), mediante un archivo de configuración. A grandes rasgos busca permitir replicar un entorno en multiples maquinas, de forma automatica, de manera de no tener que estar instalando manualmente dependencias o haciendo malabares como agregar las aplicaciones externas al control de versiones o tener que compilar manualmente librerias, o peor, pedirle al puto señor sysadmin (sry sysadmins, no es su dia, asi que se me permite putearlos) que instale los paquetes.

¿Dije que Buildout genera un entorno aislado para instalar todas esas cosas?

Ahora mostraré como “envolver” un proyecto django para facilitar el depliege; es posible convertirlo en un egg, pero en este ejemplo no lo haré, simplemente porque nunca lo he hecho :]

Obtener Buildout

Aquí hay 2 formas, a mano o usando una herramienta (tambien python) llamada paster; la gracia de usar paster es que genera un template y ahorra mucho tiempo, así que lo haré de esa forma.

Paster esta en los repositorios de Ubuntu, pero es mucho mejor instalarlo usando pip (el gestor de paquetes python :O)

#si no tenemos pip instalado
easy_install pip
pip install paster
pip install fez.djangoskel

Con esto instalamos pip, paster y los templates para proyectos Django en distintas variedades

Ahora para asegurarnos que todo este correctamente instalado

$ paster create --list-templates
Available templates:
  basic_package:             A basic setuptools-enabled package
  django_app:                Template for a basic Django reusable application
  django_buildout:           A plain Django buildout
  django_namespace_app:      Template for a namespaced Django reusable application
  django_namespace_project:  Template for a namespaced Django project
  django_project:            Template for a Django project
  paste_deploy:              A web application deployed through paste.deploy

Crear y configurar el proyecto

El template que nos interesa es django_buildout

$ paster create -t django_buildout directorio

Nos pedirá que ingresemos la version de Django con la que se ha de correr el proyecto, es posible pasar “trunk” para usar la versión de desarrollo, pero dado que es muy inestable lo mejor es casarse desde un principio con una versión.

También nos solicitará un nombre de proyecto; por lo general lo dejo como viene por defecto.

Con esto creamos en “directorio” un esqueleto con una configuración estándar y un proyecto Django, el archivo “settings.py” del esqueleto es levemente distinto al que crea django con el clásico “startproject”, pero no debería influir demasiado.

Dentro del archivo ahora deberiamos tener los archivos:

  • bootstrap.py
    • El ejecutable que creara el entorno “aislado” de Buildout.
  • buildout.cfg
    • El archivo de configuración por defecto
  • devel.cfg
    • Permite agregar modos de configuración extras para desarrollo, si usas aplicaciones como django-debug-toolbar, south, werkzeug junto a django-extensions para depurar, deberias agregarlo aquí como se mostrará después. No es necesario repetir lo que hay en “buildout.cfg” ya que este archivo lo extiende.
  • README.txt
    • Un archivo vacío para poner notas sobre la instalación, vale la pena poner algo, para que otras personas puedan usar el proyecto

Luego lo que debemos hacer es modificar el archivo buildout.cfg lo que agregaré son cosas básicas para el funcionamiento sin problemas de django; el archivo debe quedar algo asi.

[buildout]
parts =
   zlib
   PIL
   django

eggs =
   PIL

[zlib]
recipe = hexagonit.recipe.cmmi
url = http://zlib.net/current/zlib.tar.gz
configure-options = --shared

[PIL]
recipe = zc.recipe.egg:custom
egg = PIL
find-links = http://dist.repoze.org
include-dirs = ${zlib:location}/include
library-dirs = ${zlib:location}/lib
rpath = ${zlib:location}/lib

[django]
recipe = djangorecipe
version = 1.2.1
project = project
wsgi=true
settings=production
eggs = ${buildout:eggs}

Vale la pena destacar que la url de zlib que coloque es para descargar siempre la ultima version de la libreria; se puede reemplazar con otra ruta donde estén los fuentes de la versión que necesites. Tambien puedes modificar la versión de django a instalar.

Entender las lineas recipe es fundamental para hacer que Buildout funcione, hexagonit.recipe.cmmi por ejemplo descarga lo que diga la linea url y hace un configure, make, make install (por eso CMMI) por lo que funciona con cualquier fuente; por otro lado zc.recipe.egg simplemente instala huevos python, pero con el sufijo :custom permite especificar la localización de las librerías necesarias para que PIL funcione, de otra manera va a buscar las del sistema que lo mas probable es que no estén (esa es la idea de usar Buildout ¿no?); para mas información es mejor ver la lista de estas y documentacion de cada una y de buildout.

Para agregar una dependencia, digamos por ejemplo que nuestro proyecto usa django-tables para mostrar la información. Entonces vemos si en PyPi (el repo de apps python) esta disponible:

$ pip search django-tables
django-tables             - Render QuerySets as tabular data in Django.

Si  es asi, solo la agregamos a eggs de la seccion buildout (eggs = PIL django-tables). Hay que tener cuidado si no depende de algo mas

En caso de que no esté, pero tiene un repositorio, se puede usar otra receta para obtenerlo y agregar en la seccion django, extra-paths = ${app:location} pero para eso es mejor ver la documentación, puede que a futuro haga un post sobre agregar dependencias desde controles de versiones, para no extender tanto este post.

Lo ultimo es ejecutar bootstrap.py (python bootstrap.py) que creara el entorno y sus carpetas.

En este momento puedes copiar el contenido de tu proyecto (si es que lo tienes) a la carpeta project que hay dentro del directorio, asi como agregar todo al sistema de control de versiones que uses, es conveniente solo agregar al control solo la carpeta de tu proyecto django, los .cfg que editamos y bootstrap.py; es decir, solo lo que había en el template que paster nos creó y tu proyecto;en git yo ocupo un archivo .gitignore como este:

*.pyc
*.pyo
*.swp
*.pyc
bin
develop-eggs
downloads
eggs
parts

De esta manera no agrego accidentalmente archivos que no quiero al repositorio.

Ejecutar buildout

Ahora que ya esta todo listo, lo unico que hay que hacer es ejecutar bin/buildout esto descargara e instalará las dependencias, si deseas usar la configuracion de desarrollo, simplemente usas un argumento

bin/buildout -c devel.cfg

Si modificas buildout.cfg solo necesitas volver a ejecutar bin/buildout

Bueno, eso es todo; cuando tu u otra persona necesite desarrollar o deplegar el proyecto, solo debera correr el bootstrap.py y luego bin/buildout y listo. Además buildout genera un archivo WSGI en bin/django.wsgi por defecto; asi que solo queda configurar el sitio en el servidor web usando ese archivo, que viene con las rutas de las distintas dependencias apuntando al entorno que buildout creó.

Algunas veces es necesario un entrono mas aislado, por lo que puedes usar virtualenv; pero a mi juicio es demasiada paranoia, ya que virtualenv modifica el PATH y entorpece desplegar las aplicaciones, y a cambio no ofrece mucho mas que lo que tenemos con Buildout.

Me quedan pendientes algunas cosas, como poder generar una configuracion de VirtualHost autmáticamente para apache que es bastante util y algunas notas puntuales sobre recetas, espero escribirlas mas adelante para que no se me olviden (razón por la que hago este post, ya que comenzé un proyecto nuevo y olvide muchos detalles xD).

Algunos links utiles (la mayoria mas completos que esta guia rapida):

Anuncios

2 Comments

  1. excelente post y muy bien explicado, soy nuevo en django y python y post como estos ayudan mucho pero espero que me puedas disculpar por mi pregunta pero cuando se hace una aplicion en django se debe escojer un servidor web por lo general apache, la pregunta es al generar la aplicacion con buildout como se servirian los archivos o como funcionaria

    • No se a que te refieres con “servir los archivos”, me imagino que es para servir los archivos estaticos (imagenes, javascript, css, etc).
      Si es asi, entonces va a depender del servidor web que utilices, en apache puedes servir tanto tu aplicacion (con mod_wsgi) como los archivos, solo debes agregar un alias de una ruta (generalmente /media/ apuntando al directorio donde estan los archivos.

      De todas maneras eso esta bien cubierto en el manual de django e incluso con archivos de config de ejemplo, asi que pueder revisar por ahi


Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: