Automatización de despliegue con GitLab CI/CD

Este documento explica paso a paso cómo está configurado el sistema de CI/CD de nuestro proyecto Laravel en GitLab, utilizando un archivo .gitlab-ci.yml con tres fases principales: documentación, test en staging y despliegue en producción.


📋 Definición de etapas (stages)

En la parte superior del archivo .gitlab-ci.yml, definimos las etapas por las que pasarán nuestros pipelines:

stages:
  - pages
  - test
  - deploy

Esto indica a GitLab el orden de ejecución:

  1. pages: generación de documentación del proyecto con MkDocs.
  2. test: ejecución de pruebas en entorno staging.
  3. deploy: despliegue automático a producción por SSH.

📚 Job: Generación de documentación (pages)

pages:
  stage: pages
  image: python:3.10
  script:
    - pip install mkdocs
    - mkdocs build --site-dir public
  artifacts:
    paths:
      - public
  only:
    - main

🔍 Explicación:

  • image: usamos una imagen oficial de Python, necesaria para instalar MkDocs.
  • script: instalamos MkDocs y generamos la documentación en el directorio public.
  • artifacts: guardamos el contenido generado (public) para ser visualizado o publicado.
  • only: main: este job se ejecuta solo cuando se hace push a la rama main.

🧪 Job: Pruebas automáticas (test)

test:
  stage: test
  image: php:8.2
  services:
    - mysql:8.0
  variables:
    MYSQL_ROOT_PASSWORD: root
    MYSQL_DATABASE: tutorial
    MYSQL_USER: sail
    MYSQL_PASSWORD: password
    DB_HOST: mysql
    DB_USERNAME: sail
    DB_PASSWORD: password
  before_script:
    - cd laravel-9.0-main
    - apt-get update && apt-get install -y unzip git zip curl libzip-dev libpng-dev libonig-dev
    - docker-php-ext-install pdo_mysql zip
    - curl -sS https://getcomposer.org/installer | php
    - php composer.phar install
    - cp .env.example .env
    - php artisan key:generate
    - php artisan migrate:fresh --seed
  script:
    - php artisan test
  only:
    - staging

🔍 Explicación:

  • image: usamos PHP 8.2 para ejecutar Laravel.
  • services: usamos un contenedor mysql:8.0 como base de datos temporal.
  • variables: definimos credenciales y entorno para conectarse a la base de datos MySQL.
  • before_script: preparamos el entorno instalando extensiones necesarias, dependencias con Composer y configurando .env.
  • script: ejecutamos los tests automatizados de Laravel con php artisan test.
  • only: staging: este job se ejecuta solo en la rama staging, pensada para pruebas.

🚚 Job: Despliegue en producción (deploy)

deploy:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client rsync git sshpass
    - echo $SSH_HOST
  script:
    - sshpass -p "$PASSWORD" ssh -tt -o StrictHostKeyChecking=no root@$SSH_HOST "
      git config --global --add safe.directory /var/www/html/proyecto-laravel &&
      cd /var/www/html/proyecto-laravel && 
      git checkout deploy &&
      git pull &&
      cd laravel-9.0-main &&
      composer install --no-interaction &&
      php artisan migrate --force &&
      npm install &&
      npm run build &&
      systemctl restart nginx"
  only:
    - deploy
  environment:
    name: production

🔍 Explicación:

  • image: usamos Alpine Linux por su ligereza.
  • before_script: instalamos herramientas necesarias (sshpass, git, rsync, etc.).
  • script:
  • Nos conectamos por SSH a la máquina de producción.
  • Actualizamos el repositorio (checkout de la rama deploy, pull).
  • Instalamos dependencias PHP y Node.js.
  • Aplicamos migraciones con --force.
  • Compilamos el frontend con Vite.
  • Reiniciamos el servidor NGINX.

  • only: deploy: este job se ejecuta exclusivamente cuando se hace push a la rama deploy.


✅ Resultado del pipeline

Cada rama tiene su función:

  • main: genera y publica la documentación.
  • staging: ejecuta pruebas para garantizar que todo funciona.
  • deploy: realiza el despliegue real del proyecto.

📸 Vista general de los pipelines

A continuación, una vista general desde GitLab mostrando la ejecución exitosa de cada pipeline según su rama:

Vista de pipelines en GitLab


Con esta configuración conseguimos:

  • Validación automática del código antes del despliegue.
  • Documentación siempre actualizada en main.
  • Despliegue seguro y automático a producción desde deploy.