Creación de proyectos en Webistrano

Este artículo finaliza la instalación de Webistrano y la distribución de una aplicación simple. En los dos artículos anteriores se hizo la instalación de Capistrano y Webistrano, configurando Apache para que alojara a este último como un servidor Web Vitual. Aquí veremos el manejo básico de proyectos, etapas, equipos y usuarios en Webistrano.


Instalación de Capistrano-Webistrano| Instegración bajo Apache

Distribuyendo una aplicación no Rails

Ahora la parte divertida.

Capistrano clasifica las cosas en proyectos, etapas y recetas. Cada aplicación que desee que sea distribuida por Capistrano debe tener su propio proyecto. Cada proyecto debe tener una etapa al menos y opcionalmente permitir la configuración de etapas y de distribución.

Los equipos se deben de agregar de manera global y constituirán los objetivos de una distribución para un proyecto dado. Los equipos pueden incluir servidores de Web, de applicaciones y de bases de datos.

Las distribuciones en Capistrano se colocan en un subdirectorio dentro del directorio release que se nombra en base a la fecha y la hora de la distribución. De manera predeterminada se mantienen 5 liberaciones con la información para deshacer los cambios. Hasta el momento en que una distribución es exitosa se acualiza un enlace hacia ese directorio de distribución (simlink que lleva el nombre predeterminado de current y puede modificarse mediante la variable de configuración current_path). Este enlace es el que debe considerarse en la configuración del servidor de Apache (de hecho debe ser el valor de DocumentRoot).

Capistrano también crea un directorio compartido cuyo nombre es shared que se enlaza en cada liberación y se utiliza para almacenar las bitácoras y otros datos adicionales que deban mantenerse entre cada distribución.

Para aplicaciones que no sean de tipo Rails usted deberá utilizar el tipo de proyecto Pure File al momento de crearlo. Después de la creación del proyecto podrá agregar las variables de configuración específicas para ese proyecto. Se recomienda utilizar la opción :export en lugar de :checkout para la instrucciốn deploy_via para las distribuciones de producción de la aplicación subversion; de esta forma no se expondrán los directorios .svn. Utilice un usuario de SSH que tenga los permisos suficientes para crear directorios donde la distribución se lleve a cabo, o epecifique el valor de user_sudo en true y cree una variable de configuración runner admin_runner:admin_runner en el archivo /etc/sudoers.

Agregue una etapa para producción a su proyecto mediante production. En la página Manage Hosts agregue un equipo por cada servidor donde se instalará la applicación. Después agregue cada equipo como un objetivo target para la etapa production de su proyecto.

En este punto puede ejecutar la tarea Setup para la etapa production. Esta es una tarea que se ejecuta sólo una vez y simplemente crea los subdirectorios.

Asumamos que todo salió bien, intente entonces una distribución con Deploy y vea si finaliza son errores. Deberá tener cuidado de asignar los permisos adecuados a los directorios.

Para un entorno de aplicaciones PHP hay un par de tareas adicionales que vamos a ejecutar además de las tareas que realiza Capistrano. Realícelas creando recetas personalizadas en la página Manage Recipes en Webistrano. Las recetas son simplemente procedimientos escritos en Ruby. A continuación verá el código de estas recetas:

namespace :deploy do
    task :setup, :except => { :no_release => true } do
        dirs = [deploy_to, releases_path, shared_path]
        dirs += shared_children.map { |d| File.join(shared_path, d) }
        run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
        run "chmod 777 #{shared_path}/log"
    end
 
    task :finalize_update, :except => { :no_release => true } do
        run "mkdir -p #{latest_release}/app/tmp"
        run "chmod -R 777 #{latest_release}/app/tmp"
        run "rm -rf #{latest_release}/app/logs"
        run "ln -s #{shared_path}/log #{latest_release}/app/logs"
        run "cp #{latest_release}/public_html/.htaccess-production #{latest_release}/public_html/.htaccess"
        run "cp #{latest_release}/app/config/config-production.php #{latest_release}/app/config/config.php"
        run "cp #{latest_release}/app/config/db-default.php #{latest_release}/app/config/db.php"
        run "cp #{latest_release}/app/config/memcache-default.php #{latest_release}/app/config/memcache.php"
    end
end

Si aún no está familiarizado con Ruby, le diré que este código esencialmente sobrescribe dos tareas en el espacio de nombres :deploy.

El primer :setup simplemente duplica la funcionalidad de base discutida anteriormente (crear las liberaciones y los directorios compartidos) y cambia los permisos de acceso a dichos directorios.

La segunda tarea :finalize_update, realiza una serie de tareas de configuración para una aplicación PHP construida en mi framework. También notará que he eliminado el directorio de las bitácoras y el enlace al directorio de bitácoras compartidas. De esta forma todas las liberaciones enviarán sus bitácoras al mismo directorio.

Todos estos procedimientos son instrucciones en la línea de comandos. De manera alternativa, puede hacer una variedad de cosas explotando las capacidades del menguaje Ruby y de cualquier gem que usted escriba. Cosas como acceder a las APIs de CDN para eliminar imágenes, archivos JS o CSS del directorio de cache, etc.

Distribuyendo aplicaciones Django

En primera, lo mejor es que distribuya las aplicaciones Django mediante el módulo mod_wsgi. Para facilitar el proceso de distribución cree el guión app.wsgi de la siguiente forma:
1 import os
2 import sys
3
4 appdir = os.path.normpath(os.path.join(os.path.realpath(os.path.dirname(__file__)), '..'))
5 sys.path.insert(0, appdir)
6 os.environ['DJANGO_SETTINGS_MODULE'] = 'settings'
7 os.environ['PYTHON_EGG_CACHE'] = os.path.join(appdir, '.python-eggs')
8 import django.core.handlers.wsgi
9 application = django.core.handlers.wsgi.WSGIHandler()
Este código evita que usted escriba las trayectorias de archivo en los guiones wsgi (y por lo tanto que tenga que cambiarlos al momento de distribuirlos). El código asume la siguiente estructura de archivos:
.python-eggs (egg cache)
apps (apps path is added to python system path in settings.py)
public (where your .wsgi script resides)
site_media
templates
settings.py
settings-production.py (used for deploy)
urls.py
...
Si sigue esta convención, la siguiente receta de Capistrano trabaja muy bien:
01 namespace :deploy do
02 task :setup, :except => { :no_release => true } do
03 dirs = [deploy_to, releases_path, shared_path]
04 dirs += shared_children.map { |d| File.join(shared_path, d) }
05 run "#{try_sudo} mkdir -p #{dirs.join(' ')} && #{try_sudo} chmod g+w #{dirs.join(' ')}"
06 run "chmod 777 #{shared_path}/log"
07 end
08
09 task :finalize_update, :except => { :no_release => true } do
10 run "rm -rf #{latest_release}/logs"
11 run "ln -s #{shared_path}/log #{latest_release}/logs"
12 run "cp #{latest_release}/settings-production.py #{latest_release}/settings.py"
13 run "mkdir -p #{latest_release}/.python-eggs"
14 run "chmod 777 #{latest_release}/.python-eggs"
15 end
16 end

Instalación de Capistrano-Webistrano| Instegración bajo Apache