En el anterior post vimos cómo realizar la configuración previa de SSH, necesaria para realizar un despliegue con Deployer. En este veremos cómo realizar un despliegue sencillo y alguna de las opciones básicas de configuración y uso que ofrece Deployer.
Para ver el uso básico de un despliegue con Deployer podemos empezar usando un proyecto muy simple, que conste de un único fichero index.php. Por ejemplo, el clásico Hello World!:
<?php echo "Hello World!";
Este proyecto deberá estar versionado en un repositorio git (accesible desde la máquina destino), y el fichero index.php guardado en la rama master del mismo. Una vez creado el proyecto y el repositorio, podemos empezar a definir el script de despliegue con Deployer. Para ello, nos posicionamos con la terminal en cualquier directorio (puede ser el mismo del proyecto) y ejecutamos:
$ dep init
Deployer nos preguntará de qué tipo es nuestro proyecto (por ejemplo Symfony, Laravel, etc). En nuestro caso elegimos Common:
Please select your project type (defaults to common): [0] Common [1] Laravel [2] Symfony [3] Yii [4] Zend Framework [5] CakePHP [6] CodeIgniter [7] Drupal >
Deployer creará en ese directorio un script llamado deploy.php con el siguiente contenido por defecto:
<?php namespace Deployer; require 'recipe/common.php'; // Configuration set('ssh_type', 'native'); set('ssh_multiplexing', true); set('repository', 'git@domain.com:username/repository.git'); set('shared_files', []); set('shared_dirs', []); set('writable_dirs', []); // Servers server('production', 'domain.com') ->user('username') ->identityFile() ->set('deploy_path', '/var/www/domain.com'); // Tasks desc('Restart PHP-FPM service'); task('php-fpm:restart', function () { // The user must have rights for restart service // /etc/sudoers: username ALL=NOPASSWD:/bin/systemctl restart php-fpm.service run('sudo systemctl restart php-fpm.service'); }); after('deploy:symlink', 'php-fpm:restart'); desc('Deploy your project'); task('deploy', [ 'deploy:prepare', 'deploy:lock', 'deploy:release', 'deploy:update_code', 'deploy:shared', 'deploy:writable', 'deploy:vendors', 'deploy:clear_paths', 'deploy:symlink', 'deploy:unlock', 'cleanup', 'success' ]); // [Optional] if deploy fails automatically unlock. after('deploy:failed', 'deploy:unlock');
Como se puede ver en la segunda línea, Deployer ha incluido el fichero recipe/common.php ya que hemos elegido el tipo Common al realizar el dep init. Esto es lo que Deployer llama una receta (recipe), es decir, una serie de tareas y configuración por defecto adaptada a diferentes tipos de proyectos y frameworks PHP.
A continuación viene la sección de configuración general (// Configuration), en la que indicamos que utilizaremos SSH nativo como medio de conexión y la URL al repositorio de código (set(‘repository’, …)). Por defecto, se obtiene el código de la rama master del repositorio, pero se puede modificar añadiendo la instrucción set(‘branch’, ‘nombre-de-la-rama’);.
El despliegue con Deployer nos permite además definir ficheros y directorios compartidos (set(‘shared_files’, []);, etc.), es decir, que no cambian entre despliegues. Esto es especialmente útil para directorios de logs, sesiones o ficheros de configuración que no deberían sobreescribirse con cada despliegue. En este caso no vamos a definir ninguno.
En la siguiente sección (// Servers) definiremos el servidor en el que vamos a realizar el despliegue (podemos añadir más si es necesario):
Por último viene la sección de tareas (// Tasks) en la que se definen los pasos necesarios para realizar el despliegue. Por ejemplo, se está definiendo una tarea task(‘php-fpm:restart’, … para resetear PHP-FPM, que se ejecutará después de la tarea deploy:symlink (crear el enlace simbólico a la release actual). Si no utilizamos PHP-FPM, es necesario eliminar esta tarea.
A continuación se define la tarea principal de despliegue deploy especificando una serie de sub-tareas a realizar. Aconsejo consultar la documentación y el código de Deployer para saber más acerca de la función de cada una de ellas.
En nuestro proyecto Hello World, además es necesario eliminar la línea ‘deploy:vendors’,, correspondiente a la tarea de instalación de Composer, ya que no estamos utilizando librerías de terceros. Así pues, nuestro script deploy.php quedaría parecido a:
<?php namespace Deployer; require 'recipe/common.php'; // Configuration set('ssh_type', 'native'); set('ssh_multiplexing', true); set('repository', 'git@domain.com:username/repository.git'); //Modificar // Servers server('production', 'domain.com') //Modificar ->user('username') //Modificar ->identityFile() ->set('deploy_path', '/var/www/hello-world'); // Tasks desc('Deploy your project'); task('deploy', [ 'deploy:prepare', 'deploy:lock', 'deploy:release', 'deploy:update_code', 'deploy:shared', 'deploy:writable', 'deploy:clear_paths', 'deploy:symlink', 'deploy:unlock', 'cleanup', 'success' ]); // [Optional] if deploy fails automatically unlock. after('deploy:failed', 'deploy:unlock');
…donde será necesario modificar los valores de las líneas marcadas con //Modificar para cada caso concreto.
Una vez configurado nuestro script deploy.php, podemos realizar el despliegue con Deployer a través del comando:
$ dep deploy
o en el caso de haber definido varios servidores:
$ dep deploy [nombre-servidor]
por ejemplo para el servidor production (server(‘production’, …):
$ dep deploy production
Si todo va bien deberíamos ver el siguiente resultado:
<img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:prepare <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:lock <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:release <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:update_code <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:shared <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:writable <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:clear_paths <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:symlink <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task deploy:unlock <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task cleanup <img draggable="false" class="emoji" alt="✔" src="https://s.w.org/images/core/emoji/12.0.0-1/svg/2714.svg"> Executing task success Successfully deployed!
Si revisamos el directorio configurado en la variable deploy_path en la máquina destino (en este ejemplo /var/www/hello-world) veremos que Deployer ha creado las siguientes carpetas:
$ ls -al total 20 drwxr-xr-x 5 root root 4096 Feb 19 22:49 . drwxrwxr-x 5 root root 4096 Feb 19 22:45 .. lrwxrwxrwx 1 root root 10 Feb 19 22:49 current -> releases/1 drwxr-xr-x 2 root root 4096 Feb 19 22:53 .dep drwxr-xr-x 3 root root 4096 Feb 19 22:49 releases drwxr-xr-x 2 root root 4096 Feb 19 22:45 shared
Si realizamos otro despliegue con Deployer veremos que se coloca en la carpeta /releases/2 y actualiza el enlace simbólico current para que apunte a esta carpeta. Esto nos permite realizar despliegues sin necesidad de parar la aplicación y mantener las releases anteriores en caso de que algo vaya mal y queramos hacer un rollback. Si queremos volver a la versión anterior podemos ejecutar el comando:
$ dep rollback
…que actualizará el enlace simbólico current para que apunte a la release anterior.
En este post hemos visto lo básico para instalar, configurar y utilizar Deployer para desplegar una aplicación PHP muy simple. Frente a otras alternativas, un despliegue con Deployer tiene la ventaja de estar escrito en un lenguaje familiar para los desarrolladores de aplicaciones PHP, de manera que es más sencillo configurarlo y extenderlo para adecuarlo a cada necesidad. Además la configuración del fichero deploy.php es sencilla y el resultado acaba siendo bastante legible y fácil de entender.
Si os habéis quedado con ganas de más os recomiendo echarle un vistazo a la documentación de la herramienta, ya que permite casos de uso más avanzados como: