Desplegando aplicaciones Symfony 2 con Capifony: el recopetín
Si eres de los que pierde mucho tiempo desplegando aplicaciones web entonces Capifony te va a encantar.
Se trata de un paquete de tareas orientadas al despliegue de aplicaciones en diferentes entornos y servidores ya sean locales o remotos. Está basado en ruby
En resumen: con Capifony podrás desplegar tus aplicaciones en múltiples servidores desde tu máquina de una manera muy cómoda y segura. Si algo sale mal, basta con ejecutar un comando para revertir el código del servidor a la anterior release en cuestión de segundos
Quizás quieras utilizarlo en el arranque de una instancia de EC2 para descargar la última versión del código y empezar a funcionar. Todo es posible
En nuestro caso decidimos darle una oportunidad en un proyecto que estamos ayudando a construir con Symfony 2 y Amazon Web Services. Los resultados han sido más que satisfactorios. Vuela :)
Sin embargo, nos hemos topado con algunos obstáculos y queremos dejar aquí expuesto un resumen de nuestro aprendizaje
No perdáis de vista el site oficial, tiene una guía y consejos interesantes
Haremos varias suposiciones porque se adaptan a nuestro caso particular. Aun así, intentaremos explicar todas las opciones
Usamos Symfony 2 con composer
Nuestro server remoto soporta facl
Usamos Github
Lo primero es instalar Capifony
gem install capifony
Nos situamos en la raiz de nuestro proyecto y ejecutamos el script de inicio
cd /ruta/a/tu/proyecto capifony .
Este comando nos habrá generado un archivo en /ruta/a/tu/proyecto/app/config/deploy.rb que vamos a editar a nuestro gusto hasta dejar algo parecido a esto
set :application, "Tu proyecto" set :app_path, "app" set :web_path, "web" set :domain, "tuservidor.com" # Servidor remoto set :user, "usuario" # Usuario ssh set :scm, :git set :repository, "[email protected]:usuario/repositorio.git" set :branch, "master" ssh_options[:forward_agent] = true default_run_options[:pty] = true set :update_vendors, false set :use_composer, true set :deploy_to, "/var/www/tuproyecto" # Ruta del de set :deploy_via, :remote_cache #set :deploy_via, :copy #set :deploy_via, :rsync_with_remote_cache set :use_sudo, false set :shared_files, ["app/config/parameters.yml"] set :shared_children, [app_path + "/logs", web_path + "/uploads", "vendor"] set :writable_dirs, ["app/cache"] set :webserver_user, "www-data" set :permission_method, :acl set :model_manager, "doctrine" # Or: `propel` role :web, domain # Your HTTP server, Apache/etc role :app, domain # This may be the same as your `Web` server role :db, domain, :primary => true # This is where Symfony2 migrations will run set :keep_releases, 3 # Be more verbose by uncommenting the following line # logger.level = Logger::MAX_LEVEL
A continuación, vamos a comentar aquellas líneas menos evidentes
domain es el host al que Capifony se conectará vía ssh mientras que con user configuramos el usuario con que lo hará
ssh_options[:forward_agent] hace que el servidor remoto utilice tu clave local privada para identificarse con Github. Activando default_run_options[:pty] garantizamos que el server pueda preguntarnos por una password u otra información. Puede ser útil en ciertos casos, yo personalmente la tengo activada
Con esta configuración de update_vendors y use_composer indicamos que no utilice bin/vendors sino el Composer para actualizar los vendors de nuestra aplicación
La política de despliegue está manejada por deploy_via y es la que sigue
copy clona el repositorio de github en una release del servidor remoto. En este caso es el servidor remoto el que conecta a Github
remote_cache mantiene actualizado un repositorio en el servidor remoto bajo el directorio shared/cached-copy del despliegue salvo que se le diga otra cosa. Cuando ejecutamos cap deploy se actualiza ese repositorio remoto desde Github y se ejecuta el despliegue. De esta forma sólo se descargan los últimos cambios. En este caso es el servidor remoto el que conecta a Github
rsync_with_remote_cache estará solo disponible instalando el gem correspondientegem install capistrano_rsync_with_remote_cache. Funciona como remote_cache salvo que mantiene una copia local .rsync_cache en en la raiz de nuestro proyecto salvo que se le diga lo contrario y la mantiene sincronizada con la remota. En este caso el equipo local es el que conecta a Github
Desactivar use_sudo evita que la estructura de ficheros desplegada la cree el usuario root sino el usuario con el que conectamos vía ssh
Seguramente queramos que algunos ficheros sean compartidos entre releases, como ficheros de configuración que no están en el repositorio. En ese caso añadiremos esos ficheros a shared_files. Capifony creará un directorio shared en el servidor remoto donde deberemos alojar esos ficheros y en cada release creará enlaces simbólicos hacia ellos. Ojo, si los ficheros no están en el repositorio queda de nuestro lado ponerlos en el directorio correspondiente del servidor remoto antes de hacer nuestro primer despliegue. Ej: parameters.yml
Capifony también permite compartir directorios completos entre releases aplicando lo descrito para el caso anterior. Esto es regulado con shared_children
Por otro lado, hay directorios de cada release en los que el usuario www-data (o equivalente) del servidor remoto tiene que poder escribir. Por ejemplo app/cache. Para eso sirve writable_dirs. Capifony se asegurará de que queden listos para escribir por el usuario indicado en www-data a través de varias opciones de permission_method
acl ejecuta un comando setfacl en el servidor remoto
chmod otorga a los directorios permisos globales de escritura
chown ejecuta un comando chown en el servidor remoto. Es incompatible con tener use_sudo desactivado
Cuando tengamos nuestro fichero deploy.rb listo necesitaremos crear la estructura de directorios necesaria en el servidor remoto. Para ello ejecutaremos
cap deploy:setup
Si todo ha ido bien nuestro directorio de despliegue en el servidor remoto tendrá una esctructura parecida a esta
`-- /var/www/my-app.com |-- releases `-- shared
Dentro todavía del servidor pondremos en su lugar los ficheros que no estén en el repositorio dentro del directorio shared de nuestro despliegue. Ej: shared/app/config/parameters.yml.
Es importante porque Capifony ejecuta tareas de nuestra app de Symfony en el servidor remoto y necesita que esté correctamente configurada
Una vez todo esté listo ejecutaremos en nuestra máquina local
cap deploy cap deploy:set_permissions
Si te ha funcionado a la primera, enhorabuena
Si no, mantén la calma. Consulta la página de Capifony. Presta especial atención a los temas relacionados con conectividad y permisos. Recuerda también que ciertas tareas de Symfony se ejecutan en el servidor remoto y si fallan allí el despliegue se abortará
Espero que este post le haya sido de ayuda a alguien. Si véis algún error en el post no dudéis en comentarlo