DEV Community

Emmanuel Barturen
Emmanuel Barturen

Posted on

Entrega continua con Bitbucket pipelines, Digital Ocean y Laravel

En esta guía vamos a crear un autodeploy basado en los commits y pull request hace una rama.

Esta es una versión básica donde se sincroniza los nuevos archivos y modificados del repositorio bitbucket hacia digitalocean. Sin el uso de docker

Para este ejemplo vamos a tener 2 Droplets, uno para testing y otro para producción. Tengo bitbucket en lenguaje inglés

Pasos que van a suceder

  1. Al actualizar la rama master vamos a copiar los archivos nuevos al droplet
  2. vamos a ejecutar un script que instale las dependencias, ejecutar el test, agregar los permisos correctos y otras tareas que necesitemos hacer
  3. Vamos a notificar por un canal de Slack cuando el despliegue se haya realizado

Determinar ramas y entornos

El primer paso es decidir que ramas se desplegarán en qué entorno. Para este ejemplo usaremos la siguiente configuración

Branch Entorno Descripción
develop - Rama para integrar los features
master Stagging Entorno de testing / Pre-produción
prod-v1 Production Entorno de producción

Habilitar Pipelines

Ingresar a
Menu Repositorio -> Pipelines -> Starter Pipeline
Visualizaremos la pantalla siguiente:

Image description

  • Continuamos con el botón Commit File. Esto creará un archivo llamado bitbucket-pipelines.yml en la raíz del proyecto para configurar el despligue.

ES MUY IMPORTANTE NO PONER CUENTAS NI APIKEYS EN EL ARCHIVO bitbucket-pipelines.yml

Los datos sensibles los manejaremos por variables que explicaremos más adelante.

Autenticar Bitbucket con DigitalOcean

  • Creamos un SSH ingresando a
    Menu Repositorio -> Repository Settings-> Pipelines -> SSH Keys
    Veremos la siguiente pantalla
    Image description

  • Le damos click a Generate Keys

  • Ingresamos al droplet y abrimos el archivo de llaves autorizadas con el siguiente comando
    nano ~/.ssh/authorized_keys

  • Copiamos la public key que generamos en bitbucket y la pegamos en el archivo que abrimos en el droplet

  • Pegamos el IP del droplet en el input Host address y hacemos click en el botón Fetch, esto generará un fingerprint

  • Se habilitará el botón Add Host, clickeamos y esto agregará el registro a bitbucket.

Con estos pasos tenemos conectado vía SSH bitbucket con nuestro droplet Digital Ocean.

Configurar entornos

En la siguiente dirección
Menu Repositorio -> Repository Settings-> Pipelines -> Deployments

encontraremos los entornos por default que son: Test, Staging y Production

variables de entorno

Las variables de entorno son valores que sólo se pueden utilizar en el entorno que determinemos mediante la el atributo Deployment del archivo bitbucket-pipelines.yml

Si necesitamos guardar variables globales para todos los entornos estos deben ir en la siguiente ruta
Menu Repositorio -> Repository Settings-> Pipelines -> Repository Variables

Para aprender más sobre variables puedes entrar a este enlace

Para este ejemplo vamos a crear las siguientes variables

Nombre Descripción
SSH_USER nombre del usuario para la autenticación por SSH
SERVER_IP IP del droplet
SCRIPT_PATH Ruta en el droplet donde se encuentra el script que ejecutaremos luego de copiar los archivos
WEBHOOK_URL URL del webhook de Slack

Image description

Archivo bitbucket-pipelines.yml

En internet y en bitbucket hay muchos ejemplos del uso de este archivo pero para lo que necesitamos explicaremos lo básico para su funcionamiento. La configuración que vamos a usar es la siguiente:

pipelines:
  branches:
    master:
      - step:
          name: Deploy to droplet
          deployment: Staging
          script:
            - pipe: atlassian/rsync-deploy:0.7.0
              variables:
                USER: $SSH_USER
                REMOTE_PATH: '/var/www/app'
                LOCAL_PATH: '${BITBUCKET_CLONE_DIR}'
                SERVER: $SERVER_IP
                DEBUG: 'true'
            - pipe: atlassian/ssh-run:0.4.0
              variables:
                SSH_USER: $SSH_USER
                SERVER: $SERVER_IP
                COMMAND: $SCRIPT_PATH
            - pipe: atlassian/slack-notify:2.0.0
              variables:
                WEBHOOK_URL: $WEBHOOK_URL
                MESSAGE: '"Se ha desplegado correctemente la rama master en el entorno de stagging"'
Enter fullscreen mode Exit fullscreen mode

Notarán que no hay image, ya que no uso docker no lo vi necesario ponerlo y evitar demorar por la descarga de la imagen

Nombre Descripción
branches nombre que agrupa las ramas
step Paso que ejecuta una acción
name Título del paso a ejecutar
deployment entorno del que se usarán las variables
script Grupo de acciones que se ejecutarán
pipe Integración que facilita el uso de un servicio externo

Puedes encontrar muchas integraciones pipe en este enlace

Configuración en el servidor (Droplet)

Para este ejemplo crearemos la carpeta app en la siguiente dirección /var/www/app/. Dentro de esa carpeta crearemos dos archivos.

  • .env Archivo de variables de entorno que será copiado en cada despliegue
  • deploy.sh script que se ejecutará después de tener copiados los archivos

La estructura deberá quedar así:

/var/www/
└───app
│   │   .env
│   │   deploy.sh
Enter fullscreen mode Exit fullscreen mode

Rsync

Con las variables puestas correctamente rsync copiará los cambios en el servidor dentro de una carpeta llamada build que si no existe la creará.

Ejecutar bash en droplet

Como segundo paso ejecutaré un comando en el servidor que me dejará la aplicación lista para ser usada.
mi archivo se llamará deploy.sh y este será el contenido

#!/bin/bash

## Copiar archivo de variables de entorno dentro del proyecto
cp /var/www/app/.env /var/www/app/build/.env

## Ingresar a la carpeta del proyecto para ejecutar los
## siguientes comandos.
cd /var/www/app/build

## instalar composer 
composer install --no-interaction --no-progress --optimize-autoloader --no-dev

## Actualizar archivo de dependencias.
composer dump-autoload -n

php artisan migrate --seed --force

##  Asignar los permisos adecuados para un proyecto laravel
sudo chown -R $USER:www-data .
sudo find . -type f -exec chmod 664 {} \;
sudo find . -type d -exec chmod 775 {} \;
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
Enter fullscreen mode Exit fullscreen mode

notificación a slack

Finalmente con el webhook de un canal de slack se enviará la notificación cuando el proceso haya terminado

Top comments (0)