Registrarás el digest activo, descargarás una imagen nueva sin aplicarla, validarás Compose, recrearás únicamente el servicio afectado y restaurarás la referencia anterior si falla la puerta de salud.
Por qué actualizar por digest
Una etiqueta como app:stable puede apuntar hoy a una imagen y mañana a otra. Una referencia repositorio@sha256:..., en cambio, identifica contenido inmutable.

Esto mejora la reproducibilidad y la auditoría, pero no demuestra por sí solo que la imagen sea segura o compatible.
Este procedimiento está pensado para Docker Engine y Docker Compose v2 en un único host. Compose no proporciona el rollback automático de un orquestador y, con una sola réplica, puede producirse una interrupción durante la recreación.
Requisitos previos
- Docker Engine, Docker Compose v2 y Docker Buildx.
- Acceso al registro y permisos para utilizar Docker.
- Nombre exacto del servicio Compose.
- Servicio actual ya fijado mediante
repositorio@sha256:.... - Digest nuevo aprobado para la arquitectura del host.
- Healthcheck y prueba funcional representativa.
- Backup y restauración ensayada para los datos persistentes.
- Espacio para conservar las imágenes anterior y nueva.
No continúes si la actualización ejecuta una migración irreversible. Volver a la imagen anterior no revierte bases de datos, volúmenes ni efectos externos.
Paso 1: registrar el estado actual
Ejecuta estas comprobaciones desde el directorio del proyecto:
docker version
docker compose version
docker info --format '{{.OSType}}/{{.Architecture}}'
cd /ruta/al/proyecto
docker compose config -q
docker compose config --services
docker compose psObtén y valida la referencia exacta del servicio:
CID=$(docker compose ps -q web)
test -n "$CID"
OLD_IMAGE=$(docker inspect --format '{{.Config.Image}}' "$CID")
IMAGE_ID=$(docker inspect --format '{{.Image}}' "$CID")
case "$OLD_IMAGE" in
*@sha256:*) ;;
*)
echo "ERROR: el servicio A no está fijado por digest: $OLD_IMAGE" >&2
exit 1
;;
esac
docker image inspect "$OLD_IMAGE" \
--format 'id={{.Id}} repo_digests={{json .RepoDigests}}'
printf 'old_image=%s image_id=%s\n' "$OLD_IMAGE" "$IMAGE_ID"Si el servicio utiliza una etiqueta, detén el procedimiento. Este runbook exige que la versión A ya sea inmutable.
Paso 2: configurar el servicio
services:
web:
image: nginx@sha256:DIGEST_ACTIVO
ports:
- "127.0.0.1:8080:80"
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "wget -q -O- http://127.0.0.1/ >/dev/null || exit 1"]
interval: 10s
timeout: 3s
retries: 6
start_period: 10sEn este ejemplo, el digest debe haberse aprobado a partir de nginx:alpine, ya que el healthcheck depende de wget. La referencia desplegada omite la etiqueta porque el digest es quien determina el contenido.
Paso 3: verificar el digest nuevo
docker buildx version
docker buildx imagetools inspect nginx:alpine
IMAGE_REPO=nginx
NEW_DIGEST=sha256:DIGEST_NUEVO
NEW_IMAGE="$IMAGE_REPO@$NEW_DIGEST"
docker pull "$NEW_IMAGE"
docker image inspect "$NEW_IMAGE" \
--format 'repo_digests={{json .RepoDigests}} image_id={{.Id}} os={{.Os}} arch={{.Architecture}}'Comprueba que el sistema operativo y la arquitectura coincidan con el host. En imágenes multi-plataforma, documenta si aprobaste el digest del índice o el manifiesto específico.
Paso 4: validar sin aplicar
cp compose.yaml compose.rollback.yaml
cp compose.yaml compose.next.yaml
chmod 600 compose.rollback.yaml compose.next.yaml
# Reemplaza únicamente el digest en compose.next.yaml.
docker compose -f compose.next.yaml config -q
docker compose -f compose.next.yaml config --images
docker compose -f compose.next.yaml pull webconfig --images debe mostrar el digest nuevo. pull descarga la imagen sin iniciar contenedores. Si alguna comprobación falla, no reemplaces el archivo activo.

Este ejemplo presupone un único compose.yaml. Si utilizas varios archivos -f, COMPOSE_FILE, perfiles, .env o variables externas, registra y reutiliza el mismo conjunto tanto en la actualización como en el rollback.
Paso 5: actualizar únicamente el servicio
mv compose.next.yaml compose.yaml
docker compose up -d \
--wait \
--wait-timeout 90 \
--no-deps \
webCompose recreará el contenedor al detectar el cambio de imagen y conservará los volúmenes montados. --no-deps debe utilizarse solamente cuando las dependencias no necesiten reiniciarse.
Paso 6: comprobar el resultado
docker compose ps web
docker compose logs --tail=100 web
curl -fsS http://127.0.0.1:8080/
CID=$(docker compose ps -q web)
test -n "$CID"
docker inspect --format \
'ref={{.Config.Image}} image_id={{.Image}} health={{if .State.Health}}{{.State.Health.Status}}{{else}}sin-healthcheck{{end}}' \
"$CID"Acepta la actualización únicamente cuando:
- el servicio esté
running/healthy; - la prueba funcional responda correctamente;
- los logs no contengan errores nuevos;
Config.Imagecoincida con el digest nuevo;- no se hayan recreado servicios ajenos al cambio.
No uses || true para ocultar errores de validación, descarga, salud o conectividad.
Cómo volver al digest anterior
cp compose.rollback.yaml compose.yaml
docker compose config -q
docker compose config --images
OLD_IMAGE=nginx@sha256:DIGEST_ANTERIOR
docker image inspect "$OLD_IMAGE"
docker compose up -d \
--wait \
--wait-timeout 90 \
--pull never \
--no-deps \
webReemplaza DIGEST_ANTERIOR por el valor registrado en el Paso 1. --pull never obliga a utilizar la copia local de A y evita que la recuperación dependa del registro.
El rollback termina cuando Config.Image vuelve a OLD_IMAGE, el healthcheck pasa y la prueba funcional responde correctamente. Docker documenta que compose up recrea servicios cuando cambia la imagen, que --wait espera el estado saludable y que --pull never evita descargas. Docker Compose: up
Qué no revierte este rollback
- Migraciones o cambios de esquema.
- Archivos modificados en volúmenes o bind mounts.
- Mensajes, trabajos o llamadas externas ya ejecutadas.
- Datos de la capa efímera de un contenedor eliminado.
Si existen datos incompatibles, utiliza el procedimiento de restauración ensayado o un forward fix.
Por qué docker compose down no es rollback
docker compose down detiene y elimina contenedores y redes; no restaura una configuración anterior. Con --volumes también puede eliminar volúmenes. Docker Compose: down
Problemas frecuentes
El digest es incompatible: compara docker info con las plataformas del índice.
Compose conserva la imagen anterior: revisa config --images, el archivo efectivo y Config.Image. No uses --no-recreate.
El contenedor está running pero no healthy: revisa el healthcheck, el endpoint, los logs y las dependencias.
El rollback no recupera el servicio: busca incompatibilidades en datos, configuración, secretos o sistemas externos. No elimines volúmenes para forzar el arranque.
Conclusión
La actualización es recuperable solamente si registras el digest anterior, conservas la imagen local, validas antes de aplicar y repites las pruebas después de restaurar. Revertir una imagen y restaurar datos son operaciones diferentes.