Seguro que a más de uno con tan solo escuchar la palabra desplegar se le pondrán los pelos de punta. Si hay algo importante en las metodologías ágiles es el famoso DRY (don’t repeat yourself), ¿porque romper con ese enfoque para desplegar? no tiene ningún sentido desplegar a la vieja usanza, lidiando con ver que ficheros subir a producción, cuales no y empezar a subir los ficheros mediante FTP o rsync. Para evitarnos esos dolores de cabeza es donde Capifony entra en juego. Capifony nos permitirá desplegar nuestro proyecto con tan solo un comando, tan sencillo como cap deploy. Aunque a ese estado no se llega por arte de magia, primero habrá que realizar ciertas instalaciones y configuraciones, así que vamos a ello.

Salvo que se indique lo contrario las instrucciones deben ser ejecutadas DESDE donde se desplegara la aplicación.

Instalación de Capifony

Para instalar Capifony debemos tener instalado RubyGems y usaremos capistrano_rsync_with_remote_cache para poder desplegar con mayor rapidez, ya que solo se subiran los cambios realizados y no todo el respositorio.

1
2
3
4
sudo apt-get install rubygems  

sudo gem capifony
sudo gem capistrano_rsync_with_remote_cache

Configuración del entorno

Lo más cómodo (y seguro) es usar ssh con nuestra clave publica, en lugar de introducir el password cada vez que vayamos a desplegar. En caso de no tener una clave RSA generada, crearla es tan fácil como seguir los pasos del asistente que se nos muestra al ejecutar ssh-keygen

Copiar la clave publica al SERVIDOR.

Personalmente tuve algunos problemas al conectarme y tratar de copiar mi calve publica desde el terminal, así que tuve que copiarlo mediante cPanel. Hay que copiar el fichero ~/.ssh/id_rsa.pub (nuestra maquina) a ~/.ssh/authorized_keys (servidor)

Para probar si la clave quedo bien instalada, hay que ejecutar:

1
ssh usuario@ip -p puerto

Si en nuestro servidor conviven PHP 5.2 y 5.3, y en el PATH solo se encuentra la versión 5.2, debemos agregar 5.3 al PATH, sino tendremos problemas (ver la ultima sección del post). Para hacerlo tenemos que modificar el fichero (en el servidor) ~/.bashrc y añadir la siguiente linea:

1
PATH=/path/to/php5.3:$PATH

Cerramos la sesión y listo.

Configuración del proyecto

El proyecto se puede desplegar de dos maneras: obteniendo el código desde desarrollo o desde un repositorio. Se detallara como hacerlo desde un repositorio externo, para ver como hacerlo desde desarrollo consultar la documentación de Capifony.

Para crear los ficheros necesarios de capifony basta con ejecutar.

1
2
cd /path/to/project  
capifony .

Esto nos creara dos archivos:

  • Capfile: se encuentra en la raiz del proyecto, es el ejecutable que indica que estamos trabajando con Symfony.
  • Deploy.rb: este fichero se encuentra en app/config/ y se usara para configurar Capifony.

Ahora hay que editar Deploy.rb para configurar Capifony, vayamos por partes.

En esta sección se define lo que es la aplicación en si básicamente el nombre y donde se despliega.

1
2
3
4
5
6
7
8
9
10
11
12
13
#Application 

set :application, "acme"
set :domain, "#{application}.com"
set :deploy_to, "/path/to/project"
set :app_path, "app"
set :keep_releases, 3

role :web, domain
role :app, domain
role :db, domain, :primary = true

set :model_manager, "doctrine"

La mayoría de los parámetros dejan bien claro que es lo que hacen, aunque algunas aclaraciones no estarían de mas:

  • keep_releases es la cantidad de versiones (las mas nuevas) que se dejaran en el servidor al ejecutar cap deploy:cleanup, es decir si desplegamos 10 veces, tendremos 10 versiones en la carpeta releases, al realizar el clean up se eliminar las versiones mas viejas dejando únicamente las mas nuevas, en este caso tres.

  • role: si estamos desplegando solo a una maquina, hay que dejarlo tal cual esta, pero si necesitamos desplegar en varias al mismo tiempo, deberá ser algo así:

1
2
3
role :web, "subdom1.domino.com", "subdom2.dominio.com", "subdom3.dominio.com" 
role :app, "subdom1.dominio.com", "subdom2.dominio.com", "subdom3.dominio.com"
role :db, "db.dominio.com"

La configuración al repositorio es muy simple, ssh_options[:forward_agent] = true le indica a capifony que estamos usando ssh para acceder al repositorio, y que la clave se encuentra en nuestra maquina, sino habría que indicar el usuario y el password.

1
2
3
4
5
6
#Repository  
set :repository, "url"
set :scm, :git
set :deploy_via, :rsync_with_remote_cache
set :git_enable_submodules, 1
ssh_options[:forward_agent] = true

Los ficheros compartidos (shared), como lo indica su nombre son compartidos, compartidos entre versiones, por lo que se mantienen de versión a versión. En las ultimas dos opciones se indica que cada vez que se despliegue se actualicen los vendors y se instalen los assets (imágenes, css, etc que se encuentran dentro de un Bundle).

1
2
3
4
5
#Symfony2  
set :shared_files, ["app/config/parameters.ini"]
set :shared_children, [app_path + "/logs", web_path + "/uploads", "vendor"]
set :update_vendors, true
set :dump_assetic_assets, true

Finalmente se configura el acceso al servidor, si trabajamos en un servidor compartido es IMPORTANTISIMO, indicarle a Capifony que no puede usar sudo, ya que generara problemas de acceso, porque no tendremos privilegios de administrador.

1
2
3
4
#Server connection  
set :user, "user"
ssh_options[:port] = "port"
set :use_sudo, false

Despliegue

Finalmente tenemos todo listo para hacer el despliegue.

La primera vez hay que crear la estructura para Capifony. Así que desde la carpeta de nuestro proyecto ejecutamos cap deploy:setup

El cual creara una estructura como la siguiente:

1
2
3
4
5
6
7
`-- /path/to/project  
|-- current
|-- releases
`-- shared
|-- log
|-- config
`-- web

Cada vez que despleguemos se creara una carpeta en releases con el timestamp actual, y se enlazara current con la ultima versión.

Un fichero fundamental es app/config/parameters.ini, antes de ejecutar el primer despliegue, tendremos que copiarlo a shared/app/config/parameters.ini

1
scp -P puerto app/config/parameters.ini user@domain:/path/to/project/acme/shared/app/config/parameters.ini

¡Ahora si estamos listos para desplegar! cap deploy

Si, todo fue bien (esperemos que si) nuestra aplicación ya esta desplegada en producción. Y por si fuera poco Capifony nos permite acceder a la consola de Symfony directamente desde nuestra maquina, para ver todos los comando disponibles ejecutar cap -T

Posibles problemas

Sin acceso root

Leé nuevamente la sección Configuración del proyecto ;)

No such file or directory

Este error me surgio en dos ocasiones, una haciendo referencia a una carpeta de un Bundle y otra a web/images/ y web/js/. En el primer caso esto pasa cuando en el fichero deps en la URL de algún bundle tenemos git=git://... en lugar de git=http://.... En el otro caso, capifony busca las carpetas web/images/ y web/js/ por lo que al no encontrarlas lanza el error, para solucionarlo hay que crear la carpeta en cuestión en nuestro proyecto con un fichero vacio (para que la detecte git) y agregarla al repositorio.

Parse error: syntax error

En concreto este error me dio bastante problemas, después de muchas horas pude dar con la fuente del problema. El error se genera al indicar manualmente (porque el default es 5.2) el path para el ejecutable de PHP 5.3 para reinstalar los vendors, cuando se terminan de actualizar se actualiza el bootstrap, y en ese momento es cuando se genera el error. Ya que la construcción del bootstrap se hace con el ejecutable de PHP que se encuentra en el path.

Para solucionarlo hay que agregar al PATH la ruta donde se encuentra PHP 5.3. En caso de no poder modificar el path por algún motivo en concreto habría que modificar el shebang de los ficheros que están dando problemas, indicando manualmente la ruta de PHP 5.3, esto ultimo no es muy aconsejable, pero bueno nos puede sacar de un apuro.