CI/CD: del commit a producción¶
Qué significan las siglas, qué problema resuelven y cómo se ven en el pipeline del curso.
El problema que resuelve¶
Entre «el código está listo» y «los usuarios lo están usando» hay una serie de pasos repetitivos: compilar, probar, empaquetar, subir el artefacto, actualizar el servidor y comprobar que quedó arriba. Hacerlos a mano tiene un costo conocido:
| Sin pipeline | Con pipeline |
|---|---|
| «En mi máquina funciona» | La misma imagen en todos los entornos |
| Un documento de 12 pasos que alguien sigue de memoria | Los pasos son un archivo YAML versionado |
| Se despliega los viernes, con miedo | Se despliega cualquier día, varias veces |
| Nadie sabe con certeza qué versión está arriba | Cada versión tiene su commit y su tag |
| Volver atrás es un trabajo manual | Volver atrás es desplegar el tag anterior |
CI/CD es automatizar ese camino para que un cambio pueda llegar a producción en minutos, de forma repetible y sin intervención manual.
Las tres siglas¶
flowchart LR
A["Commit<br/>push a main"] --> B["Build<br/>compilar"]
B --> C["Pruebas<br/>unitarias y análisis"]
C --> D["Imagen<br/>docker build y push"]
D --> E["Despliegue<br/>al servidor"]
CI · Integración continua¶
Cada cambio que llega al repositorio se compila y se prueba automáticamente. Si algo rompe, se sabe en minutos y no cuando ya hay veinte cambios encima.
Lo que normalmente corre en esta etapa: compilación, pruebas unitarias, análisis estático (SonarQube) y, a veces, pruebas funcionales.
CD · Entrega continua (continuous delivery)¶
El resultado de la integración queda siempre listo para publicar: una imagen versionada en un registro. El despliegue existe como un botón, pero una persona decide cuándo se aprieta.
CD · Despliegue continuo (continuous deployment)¶
Nadie aprieta nada: si el pipeline pasa, el cambio llega solo al servidor. Es lo que hace el workflow del curso sobre la rama main.
La diferencia entre las dos CD es un botón
Entrega continua deja el artefacto listo y espera una aprobación. Despliegue continuo publica automáticamente. La decisión depende del riesgo del proyecto, no de la herramienta.
Qué se necesita para que funcione¶
Un pipeline no es solo el archivo YAML. Descansa sobre cuatro cosas que ya vimos en el curso:
| Pieza | Para qué | Dónde está en el curso |
|---|---|---|
| Control de versiones | Todo cambio pasa por el repositorio | Git y GitHub |
| Pruebas automáticas | Si no hay pruebas, el pipeline automatiza publicar errores más rápido | Pruebas unitarias |
| Un artefacto inmutable | La misma imagen que se probó es la que se despliega | Docker |
| Un destino reproducible | El servidor se describe en archivos, no se configura a mano | Kubernetes o Docker Compose |
El pipeline del curso, paso a paso¶
El proyecto cowork tiene un único archivo .github/workflows/build.yml con dos jobs. El flujo completo después de un git push a main:
flowchart LR
P["1 · git push<br/>a main"] --> A["2 · Runner de GitHub<br/>descarga el código"]
A --> B["3 · docker build<br/>y push a ghcr.io"]
B --> C["4 · Nuestro runner<br/>en el servidor"]
C --> D["5 · kubectl apply<br/>y rollout restart"]
D --> E["6 · Pod nuevo<br/>corriendo"]
Job 1 · construir y publicar la imagen¶
Corre en un runner de GitHub (ubuntu-latest): compilar y empaquetar no necesita acceso a nuestra red.
jobs:
build-and-publish:
name: Build and Push Image to GHCR
runs-on: ubuntu-latest
permissions:
contents: read
packages: write # para publicar en GHCR
steps:
- uses: actions/checkout@v4
- uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }} # credencial temporal del job
- run: docker build -t ghcr.io/${OWNER_LC}/${IMAGE_NAME}:${IMAGE_TAG} .
- run: docker push ghcr.io/${OWNER_LC}/${IMAGE_NAME}:${IMAGE_TAG}
Job 2 · desplegar en el servidor¶
Corre en el runner self-hosted (runs-on: main), el único que alcanza el clúster MicroK8s on-premise.
deploy-onpremise:
name: Deploy on MicroK8s On-Premise
runs-on: main # nuestro runner self-hosted
needs: build-and-publish # solo si el job anterior terminó bien
steps:
- uses: actions/checkout@v4
- run: sudo microk8s kubectl apply -f k8s/deployment.yaml
- run: sudo microk8s kubectl rollout restart deployment/cowork-api -n docsjaveriana
- run: sudo microk8s kubectl rollout status deployment/cowork-api -n docsjaveriana --timeout=300s
Tres decisiones que vale la pena entender de este archivo:
needs: si la imagen no se publicó, no se despliega nada.rollout restart: con el tag:latestelapplyno cambia el YAML, así que hay que forzar que el clúster baje la imagen nueva.rollout status: el workflow queda en rojo si el pod nuevo no llega a estar listo. Sin esta línea, un despliegue roto se reportaría como exitoso.
El detalle de cada paso está en GitHub Actions; quién lo ejecuta, en Action Runners.
El mismo pipeline, otro destino
Si el proyecto se despliega con Docker Compose en lugar de Kubernetes, solo cambian los últimos pasos: docker compose pull y docker compose up -d. Todo lo anterior —el Dockerfile, la imagen y el primer job— es idéntico.
Buenas prácticas¶
Siete reglas que evitan problemas
- Ramas cortas y commits pequeños. Un cambio pequeño que falla es fácil de encontrar y de revertir.
- El pipeline rojo se arregla primero. Un
mainroto bloquea a todo el equipo. - Nada de secretos en el YAML. Van en los secrets del repositorio o en variables de entorno.
- La imagen se construye una sola vez. La misma que pasó las pruebas es la que se despliega; no se reconstruye por entorno.
- Tags con versión, no solo
:latest. Con:latestnunca se sabe qué está corriendo ni cómo volver atrás. - El pipeline debe fallar cuando algo falla. Un paso que ignora errores da una falsa sensación de seguridad.
- Rápido. Si el pipeline tarda media hora, la gente deja de esperarlo y empieza a saltárselo.
Preguntas frecuentes¶
¿CI/CD es lo mismo que DevOps?
No. CI/CD es una práctica técnica concreta; DevOps es la forma de trabajo que la hace posible. Ver DevOps.
¿Necesito Kubernetes para hacer CI/CD?
No. El destino puede ser un servidor con Docker Compose, un servicio administrado o incluso un scp a una máquina. Lo que define CI/CD es la automatización del camino, no la tecnología del final.
¿Y si no tengo pruebas automáticas?
El pipeline sigue sirviendo para construir y desplegar de forma repetible, pero sin pruebas solo garantiza que el error llegue antes a producción. Las pruebas son lo que convierte la velocidad en seguridad.