intermediate Por Mathias Paulenko

Configurar CI con GitLab Pipelines

Cómo configurar pipelines de GitLab CI/CD para testing, building y deployment usando .gitlab-ci.yml con stages, jobs, caching y runners.

Temas: devops

Nota para desarrolladores hispanohablantes: Esta guía incluye ejemplos y convenciones de nomenclatura adaptadas a equipos que trabajan en español. Cuando existen diferencias significativas en terminología técnica entre el inglés y el español, se indican explícitamente para facilitar la comunicación en equipos multiculturales.

Descripción General

GitLab CI/CD es una plataforma de integración y despliegue continuo integrada que utiliza un archivo .gitlab-ci.yml para definir pipelines. Los jobs se ejecutan en contenedores Docker aislados en runners compartidos o auto-hospedados, facilitando la automatización de testing, building y releases.

Antes de los pipelines de CI/CD, los equipos ejecutaban tests y deployments manualmente desde máquinas locales. Esto generaba bugs de “funciona en mi laptop”, entornos inconsistentes y ninguna traza de auditoría sobre qué se desplegó y cuándo. GitLab CI/CD resuelve esto codificando cada paso del proceso de entrega en YAML versionado.

Cuándo Usar

Usa esta receta cuando:

  • Configuras testing automatizado para un proyecto hospedado en GitLab en cada push o merge request.
  • Construyes y publicas imágenes Docker a un registry como parte del proceso de release.
  • Despliegas a staging o producción con variables de entorno y aprobaciones manuales.
  • Ejecutas pipelines programadas para backups nocturnos, auditorías de dependencias o tareas de limpieza.
  • Usas runners auto-hospedados para infraestructura privada o entornos de build especializados.

Lo que funciona

  • Usa npm ci en lugar de npm install en CI para builds reproducibles que respeten estrictamente package-lock.json.
  • Cachea dependencias entre jobs usando la keyword cache para reducir drásticamente los tiempos de build.
  • Fija versiones de imágenes Docker en lugar de usar tags latest para garantizar builds reproducibles.
  • Usa artifacts para pasar archivos entre stages (ej., bundles compilados de build a deploy).
  • Configura only o rules con cuidado para evitar ejecutar jobs costosos de deploy en branches de feature.
  • Usa bloques environment para jobs de deployment para trackear qué está desplegado y habilitar rollbacks.

Errores Comunes

  • No cachear node_modules hace que cada job reinstale dependencias desde cero, desperdiciando minutos por ejecución.
  • Usar only en lugar de rulesrules es la forma moderna y más flexible de controlar la ejecución de jobs.
  • Ejecutar DIND sin TLS puede exponer el socket Docker a otros jobs en el mismo runner.
  • Almacenar secrets en .gitlab-ci.yml — siempre usa variables de CI/CD desde la configuración del proyecto.
  • Olvidar tags para runners propios hace que los jobs se encolen indefinidamente en runners compartidos.

Tips de Rendimiento

  1. Usa needs para ejecución DAG. Reduce el wall-clock time iniciando jobs tan pronto como sus dependencias terminen:
test:
  needs: [build]  # Inicia inmediatamente después de build
  1. Cachea por rama. Evita colisiones de caché entre ramas:
cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - node_modules/
  1. Usa interruptible: true para jobs de MR. Ahorra tiempo de runner cancelando pipelines reemplazados:
test:
  interruptible: true
  1. Usa imágenes pequeñas. Reduce el tiempo de pull:
# Mal: imagen grande
image: node:20

# Bien: imagen slim
image: node:20-slim

# Mejor: alpine si es compatible
image: node:20-alpine
  1. Usa before_script y after_script con cuidado. Se ejecutan para cada job en el archivo:
default:
  before_script:
    - npm ci --silent
  after_script:
    - echo "Job completado con exit code $?"

Preguntas frecuentes

¿Qué es un GitLab Runner?
Un GitLab Runner es el agente que ejecuta los jobs de un pipeline. Puede ser compartido, específico de grupo o de proyecto, y corre en Linux, Windows, macOS o Kubernetes.
¿Cómo cacheo dependencias en GitLab CI?
Usa la palabra clave cache para persistir directorios como node_modules, .m2 o .pip entre pipelines. Usa key para delimitar cachés por rama o lockfile.
¿Cuál es la diferencia entre stages y jobs?
Los stages definen fases de ejecución (build, test, deploy) que corren secuencialmente. Los jobs son las tareas individuales dentro de un stage, que pueden correr en paralelo si comparten stage.