Serie CI/CD: Configuración Inicial
La integración continua y el despliegue continuo no son conceptos nuevos, pero siguen siendo lo que separa a los equipos que entregan software con confianza de los que viven con miedo a los viernes. Automatizan pruebas y despliegues, recortan los errores que vienen de hacer las cosas a mano, y acortan el ciclo entre escribir código y verlo en producción. Esta serie arranca desde cero.
Introducción a CI/CD
CI es el hábito de integrar cambios de código al repositorio central con frecuencia, disparando pruebas automáticas en cada push. No es una herramienta. Es una disciplina que o tienes o no tienes, y se nota rápido. CD lo extiende: si las pruebas pasan, el código viaja solo hasta desarrollo, staging o producción sin que nadie tenga que acordarse de apretar un botón. La brecha entre los dos conceptos es pequeña en papel y decisiva en la práctica.
Herramientas Esenciales
No existe una combinación única que funcione para todos los proyectos. Dicho eso, estas son las piezas que aparecen más seguido y que vale la pena dominar:
- Git: Control de versiones. Sin esto no hay nada que automatizar.
- Jenkins: Servidor de automatización open-source, veterano del ecosistema CI. Muy configurable, y esa flexibilidad tiene un costo en complejidad operativa.
- Docker: Empaqueta la aplicación junto con sus dependencias en una imagen reproducible. Entierra el “en mi máquina funciona”.
- Kubernetes: Orquesta contenedores a escala, gestiona réplicas, actualizaciones y recuperación ante fallos.
- GitLab CI: CI/CD integrado directamente en GitLab, configurado mediante un archivo
.gitlab-ci.ymlen el repositorio. Es lo que vamos a usar en esta serie.
Configuración Inicial
1. Configuración de Repositorio
El repositorio es el punto de partida. Acá uso GitLab, pero el proceso con GitHub o Bitbucket es prácticamente idéntico.
# Inicializar un nuevo repositorio de Git
git init
# Añadir archivos al repositorio
git add .
# Hacer un commit inicial
git commit -m "Configuración inicial del proyecto"
# Añadir el repositorio remoto (GitLab en este caso)
git remote add origin https://gitlab.com/usuario/proyecto.git
# Enviar los cambios al repositorio remoto
git push -u origin master
2. Configuración de Jenkins
Jenkins puede volverse complicado rápido. La clave es arrancar con un pipeline mínimo y agregar complejidad solo cuando el caso lo exija, no antes. Este es el esqueleto básico:
- Instalación de Jenkins: Puedes instalarlo localmente o en un servidor dedicado.
- Configuración del Pipeline: Dentro de Jenkins, crea un nuevo proyecto y define el pipeline.
pipeline {
agent any
stages {
stage('Build') {
steps {
echo 'Construyendo...'
}
}
stage('Test') {
steps {
echo 'Ejecutando pruebas...'
}
}
stage('Deploy') {
steps {
echo 'Desplegando...'
}
}
}
}
3. Integración con Docker
Docker resuelve un problema concreto: que el entorno donde corre el código en producción sea el mismo donde se desarrolló y probó. Un Dockerfile básico para una aplicación Python luce así:
# Usar una imagen base de Python
FROM python:3.8-slim
# Establecer el directorio de trabajo
WORKDIR /app
# Copiar los requisitos y el código al contenedor
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
# Comando para ejecutar la aplicación
CMD ["python", "app.py"]
4. Despliegue con Kubernetes
Kubernetes maneja el ciclo de vida de los contenedores en producción: cuántas réplicas corren, cómo se actualizan, qué pasa cuando uno falla.
Configuración Básica de un Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: mi-aplicacion
spec:
replicas: 3
selector:
matchLabels:
app: mi-aplicacion
template:
metadata:
labels:
app: mi-aplicacion
spec:
containers:
- name: mi-aplicacion
image: usuario/mi-aplicacion:latest
ports:
- containerPort: 80
Este manifiesto levanta tres réplicas de la aplicación dockerizada y expone el puerto 80. Tres réplicas no es un número mágico. Es el mínimo razonable para absorber la caída de un nodo sin downtime, y en producción real probablemente querrás más según la carga que manejes.
Conclusión
Montar esto por primera vez puede parecer mucho. No lo es. Lo que sí requiere es orden: entender qué hace cada pieza antes de conectarlas. En el próximo artículo de la serie entramos en la configuración de pruebas automáticas y las estrategias de despliegue que realmente importan.