Docker en Pipelines de CI/CD
Qué cubre este artículo sobre Docker en CI/CD
- Qué logra CI/CD con Docker.
- GitHub Actions y GitLab CI para compilaciones de Docker.
- Compilaciones multietapa y caché.
- Testing, escaneo y despliegue en pipelines.
- Consejos para runners locales y autogestionados.
Introducción: Docker en Pipelines de CI/CD
Continuous Integration y Continuous Delivery, abreviado CI/CD, automatizan la compilación, prueba y distribución de software. Docker es ideal para esto porque las compilaciones son reproducibles y se usa el mismo entorno para tests, staging y producción. Quien automatiza la compilación, prueba y envío de imágenes Docker a una registry en cada commit ahorra tiempo y reduce errores.
Este artículo muestra cómo integrar Docker en GitHub Actions y GitLab CI, y en qué fijarse al operar con runners autogestionados.
Términos importantes
- CI: Continuous Integration, fusión y prueba regular.
- CD: Continuous Delivery o Deployment, entrega automatizada.
- Pipeline: Secuencia de varios pasos.
- Runner: Máquina que ejecuta la pipeline.
- Multi-Stage Build: Dockerfile con varios pasos de compilación.
- Layer Caching: Almacenamiento en caché de capas Docker.
- Registry: Almacén de imágenes.
- Artifact: Producto intermedio de una pipeline.
Por qué Docker en CI/CD?
- Mismo entorno para compilación, prueba y producción.
- Compilaciones reproducibles.
- Escalado sencillo mediante runners.
- Reversiones rápidas con imágenes versionadas.
- Aislamiento de dependencias.
- Implementación simple en diferentes entornos.
Ejemplo con GitHub Actions
name: Docker Build and Push
on:
push:
branches:
- main
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ghcr.io/${{ github.repository }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
Ejemplo con GitLab CI
stages:
- build
- test
- deploy
variables:
IMAGE_NAME: $CI_REGISTRY_IMAGE:latest
build_image:
stage: build
image: docker:24
services:
- docker:24-dind
script:
- docker build -t $IMAGE_NAME .
- docker push $IMAGE_NAME
only:
- main
test_image:
stage: test
image: $IMAGE_NAME
script:
- pytest
deploy_image:
stage: deploy
image: docker:24
script:
- docker pull $IMAGE_NAME
- docker run -d -p 8080:8080 $IMAGE_NAME
Compilaciones Multietapa
Las compilaciones multietapa reducen el tamaño de la imagen y mejoran la seguridad:
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages
COPY . .
CMD ["python", "main.py"]
Tests en Docker
- name: Test in Docker
run: |
docker build -t myapp:test .
docker run --rm myapp:test pytest
Escaneo de imágenes
Detecta vulnerabilidades de seguridad en la imagen:
- name: Scan image
uses: anchore/scan-action@v3
with:
image: "ghcr.io/user/repo:latest"
Caché
El caché acelera significativamente las compilaciones:
cache-fromycache-toen GitHub Actions.- Docker Layer Caching con BuildKit.
- Registry como destino de caché.
- Directorios de caché locales en runners autogestionados.
Runners Autogestionados
Para cargas de trabajo mayores o infraestructura privada, los runners autogestionados son una opción:
# Descargar y configurar el runner de GitHub Actions
./config.sh --url https://github.com/USER/REPO --token TOKEN
./run.sh
Docker debe estar instalado en el runner. Para compilaciones con GPU se necesita el Container Toolkit correspondiente.
Despliegue
Las imágenes pueden desplegarse automáticamente tras la compilación:
- En un Docker host mediante SSH.
- En un clúster Kubernetes.
- A través de Docker Swarm.
- En un servidor propio con
docker compose up -d.
Consejos
- No almacenes secretos en imágenes.
- Genera tags desde el hash de Git o la fecha.
- Detén pruebas fallidas inmediatamente.
- Activa el almacenamiento en caché de capas.
- Actualiza imágenes regularmente.
- Evita runners privilegiados cuando sea posible.
- Mantén el contexto de compilación pequeño.
Trampas típicas
- Imágenes grandes: Sin compilaciones multietapa.
- Falta de autenticación en la registry: El push falla.
- Compilaciones lentas: Sin caché.
- Secretos en variables de entorno: Se exponen en los logs.
- Runner sin Docker: La pipeline se interrumpe.
- Tags incorrectos: Sobrescriben o pierden imágenes.
- Contextos de compilación demasiado grandes: Usa
.dockerignore.
Enlaces e información adicional
- BotServ.de Docker Registry
- BotServ.de Docker Seguridad
- BotServ.de Docker Backup
- BotServ.de Kubernetes
FAQ: Docker en CI/CD
¿Necesito GitHub Actions o GitLab? Ambos funcionan. También son posibles soluciones autogestionadas como Jenkins o Woodpecker.
¿Debo compilar imágenes en cada commit?
Para main o releases etiquetados sí, para cada commit intermedio es opcional.
¿Qué tan rápidas son las compilaciones? Con caché, generalmente minutos en lugar de varios minutos cada vez.
¿Puedo ejecutar tests con GPU en CI/CD? Solo con runners que tengan GPU disponible.
¿Son seguros los runners autogestionados? Si están aislados y mantenidos. Nunca los uses en repos públicos sin protección.
Fuentes y lecturas adicionales
- GitHub Actions: https://docs.github.com/en/actions
- GitLab CI: https://docs.gitlab.com/ee/ci/
- Docker BuildKit Caching: https://docs.docker.com/build/cache/
- Docker Build-Push Action: https://github.com/docker/build-push-action
Resumen: Docker en Pipelines de CI/CD
Docker encaja perfectamente en flujos de trabajo CI/CD. GitHub Actions y GitLab CI permiten compilaciones, pruebas y despliegues automatizados de imágenes de contenedor. Las compilaciones multietapa, el almacenamiento en caché y el escaneo regular mejoran la velocidad y la seguridad. Los runners autogestionados ofrecen flexibilidad para hardware especial como GPUs. Quien proteja los secretos, use almacenamiento en caché de capas y aplique tags limpios, obtiene un flujo de trabajo de contenedores robusto.


