Introducción a Azure Pipelines con Docker
Esta guía es una contribución de la comunidad. A Docker le gustaría agradecer a Kristiyan Velkov por su valiosa contribución.
Prerrequisitos
Antes de comenzar, asegúrate de cumplir con los siguientes requisitos:
- Una cuenta de Docker Hub con un token de acceso generado.
- Un proyecto activo de Azure DevOps con un repositorio Git conectado.
- Un proyecto que incluya un
Dockerfileválido en su raíz o en el contexto de compilación adecuado.
Descripción general
Esta guía te acompaña a través de la compilación y subida de imágenes de Docker usando Azure Pipelines, lo que permite un flujo de trabajo de CI simplificado y seguro para aplicaciones contenedorizadas. Aprenderás a:
- Configurar la autenticación de Docker de forma segura.
- Configurar un pipeline automatizado para compilar y subir imágenes.
Configurar Azure DevOps para trabajar con Docker Hub
Paso 1: Configurar una conexión de servicio de Docker Hub
Para autenticarse de forma segura en Docker Hub utilizando Azure Pipelines:
- Navega a Project Settings > Service Connections en tu proyecto de Azure DevOps.
- Selecciona New service connection > Docker Registry.
- Selecciona Docker Hub y proporciona tus credenciales o el token de acceso de Docker Hub.
- Asigna un nombre reconocible a la conexión de servicio, como
my-docker-registry. - Concede acceso únicamente a los pipelines específicos que lo requieran para mejorar la seguridad y aplicar el principio de menor privilegio.
ImportantEvita seleccionar la option para conceder acceso a todos los pipelines a menos que sea absolutamente necesario. Aplica siempre el principio de menor privilegio.
Paso 2: Crear tu pipeline
Añade el siguiente archivo azure-pipelines.yml en la raíz de tu repositorio:
# Activa el pipeline con los commits en la rama main
trigger:
- main
# Activa el pipeline en pull requests destinados a la rama main
pr:
- main
# Define variables para su reutilización en todo el pipeline
variables:
imageName: 'docker.io/$(dockerUsername)/my-image'
buildTag: '$(Build.BuildId)'
latestTag: 'latest'
stages:
- stage: BuildAndPush
displayName: Build and Push Docker Image
jobs:
- job: DockerJob
displayName: Build and Push
pool:
vmImage: ubuntu-latest
demands:
- docker
steps:
- checkout: self
displayName: Checkout Code
- task: Docker@2
displayName: Docker Login
inputs:
command: login
containerRegistry: 'my-docker-registry' # Nombre de la conexión de servicio
- task: Docker@2
displayName: Build Docker Image
inputs:
command: build
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)
dockerfile: './Dockerfile'
arguments: |
--sbom=true
--attest type=provenance
--cache-from $(imageName):latest
env:
DOCKER_BUILDKIT: 1
- task: Docker@2
displayName: Push Docker Image
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
inputs:
command: push
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)
# Opcional: cerrar sesión para agentes auto-alojados
- script: docker logout
displayName: Docker Logout (Self-hosted only)
condition: ne(variables['Agent.OS'], 'Windows_NT')Qué hace este pipeline
Este pipeline automatiza el proceso de compilación y despliegue de imágenes de Docker para la rama main. Garantiza un flujo de trabajo seguro y eficiente con buenas prácticas como el almacenamiento en caché, el etiquetado y la limpieza condicional. Esto es lo que hace:
- Se activa con los commits y pull requests destinados a la rama
main. - Se autentica de forma segura con Docker Hub mediante una conexión de servicio de Azure DevOps.
- Compila y etiqueta la imagen de Docker utilizando Docker BuildKit para el almacenamiento en caché.
- Sube tanto las etiquetas de buildId como latest a Docker Hub.
- Cierra la sesión de Docker si se ejecuta en un agente Linux auto-alojado.
Cómo funciona el pipeline
Paso 1: Definir los activadores (triggers) del pipeline
trigger:
- main
pr:
- mainEste pipeline se activa automáticamente en:
- Commits subidos a la rama
main - Pull requests destinados a la rama principal
main
TipMás información: Definir activadores de pipeline en Azure Pipelines
Paso 2: Definir variables comunes
variables:
imageName: 'docker.io/$(dockerUsername)/my-image'
buildTag: '$(Build.BuildId)'
latestTag: 'latest'Estas variables garantizan la coherencia en el nombre, la versión y la reutilización en todos los pasos del pipeline:
imageName: la ruta de tu imagen en Docker HubbuildTag: una etiqueta única para cada ejecución del pipelinelatestTag: un alias estable para tu imagen más reciente
ImportantLa variable
dockerUsernameno se establece automáticamente.
Configúrala de forma segura en las variables de tu pipeline de Azure DevOps:
- Ve a Pipelines > Edit > Variables
- Añade
dockerUsernamecon tu nombre de usuario de Docker HubMás información: Definir y utilizar variables en Azure Pipelines
Paso 3: Definir etapas (stages) y trabajos (jobs) del pipeline
stages:
- stage: BuildAndPush
displayName: Build and Push Docker ImageEsta etapa se ejecuta solo si la rama de origen es main.
TipMás información: Condiciones de etapa en Azure Pipelines
Paso 4: Configuración del trabajo (job)
jobs:
- job: DockerJob
displayName: Build and Push
pool:
vmImage: ubuntu-latest
demands:
- dockerEste trabajo utiliza la última imagen de VM de Ubuntu con soporte para Docker, proporcionada por los agentes alojados por Microsoft. Se puede reemplazar con un grupo (pool) personalizado para agentes auto-alojados si es necesario.
TipMás información: Especificar un pool en tu pipeline
Paso 4.1: Descargar código (Checkout)
steps:
- checkout: self
displayName: Checkout CodeEste paso descarga el código de tu repositorio en el agente de compilación, de modo que el pipeline pueda acceder al Dockerfile y a los archivos de la aplicación.
TipMás información: Documentación del paso checkout
Paso 4.2: Autenticarse en Docker Hub
- task: Docker@2
displayName: Docker Login
inputs:
command: login
containerRegistry: 'my-docker-registry' # Reemplaza con el nombre de tu conexión de servicioUtiliza una conexión de servicio del registro de Docker preconfigurada en Azure DevOps para autenticarse de forma segura sin exponer las credenciales directamente.
TipMás información: Usar conexiones de servicio para Docker Hub
Paso 4.3: Compilar la imagen de Docker
- task: Docker@2
displayName: Build Docker Image
inputs:
command: build
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)
dockerfile: './Dockerfile'
arguments: |
--sbom=true
--attest type=provenance
--cache-from $(imageName):latest
env:
DOCKER_BUILDKIT: 1Esto compila la imagen con:
- Dos etiquetas: una con el ID de compilación único (Build ID) y otra como latest
- Docker BuildKit habilitado para compilaciones más rápidas y un almacenamiento en caché de capas eficiente
- Obtención de caché (cache pull) de la imagen latest subida más recientemente
- Lista de materiales de software (SBOM) para la transparencia de la cadena de suministro
- Atestación de procedencia (provenance attestation) para verificar cómo y dónde se compiló la imagen
TipMás información:
Paso 4.4: Subir (push) la imagen de Docker
- task: Docker@2
displayName: Push Docker Image
condition: eq(variables['Build.SourceBranch'], 'refs/heads/main')
inputs:
command: push
repository: $(imageName)
tags: |
$(buildTag)
$(latestTag)Al aplicar esta condición, el pipeline compila la imagen de Docker en cada ejecución para garantizar la detección temprana de problemas, pero solo sube la imagen al registro cuando los cambios se fusionan (merge) en la rama main, manteniendo tu Docker Hub limpio y enfocado.
Esto sube ambas etiquetas a Docker Hub:
$(buildTag)garantiza la trazabilidad por ejecución.latestse utiliza para las referencias a la imagen más reciente.
Paso 4.5 Cerrar sesión de Docker (agentes auto-alojados)
- script: docker logout
displayName: Docker Logout (Self-hosted only)
condition: ne(variables['Agent.OS'], 'Windows_NT')Ejecuta docker logout al final del pipeline en agentes auto-alojados basados en Linux para limpiar proactivamente las credenciales y mejorar la postura de seguridad.
Resumen
Con esta configuración de CI de Azure Pipelines, obtienes:
- Autenticación segura de Docker mediante una conexión de servicio integrada.
- Compilación y etiquetado automático de imágenes activados por los cambios de código.
- Compilaciones eficientes aprovechando la caché de Docker BuildKit.
- Limpieza segura con cierre de sesión en agentes persistentes.
- Compilación de imágenes que cumplen con los requisitos modernos de la cadena de suministro de software con SBOM y atestaciones.
Más información
- Documentación de Azure Pipelines: Guía completa para configurar y gestionar pipelines de CI/CD en Azure DevOps.
- Tarea de Docker para Azure Pipelines: Referencia detallada para usar la tarea de Docker en Azure Pipelines para compilar y subir imágenes.
- Docker Buildx Bake: Explora la herramienta de compilación avanzada de Docker para configuraciones de compilación complejas, multi-etapa y multi-plataforma. Consulta también la Guía de dominio de Buildx Bake para ver ejemplos prácticos y buenas prácticas.
- Docker Build Cloud: Aprende sobre el servicio de compilación administrado de Docker para compilaciones de imágenes más rápidas, escalables y multi-plataforma en la nube.