Respuesta rápida: fija el servicio a un digest (repositorio@sha256:…), valida el archivo nuevo y recrea solo ese servicio esperando a que pase el healthcheck:
mv compose.next.yaml compose.yaml

docker compose up -d \
  --wait \
  --wait-timeout 90 \
  --no-deps \
  web

Si la puerta de salud falla, vuelve al digest anterior con compose.rollback.yaml (ver «Cómo volver al digest anterior»). Volver a la imagen no revierte datos ni migraciones.

Nivel: intermedio · Requiere: Docker Engine, Docker Compose v2 y Docker Buildx

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.

Flujo de actualización por digest: descargar B, validar, recrear y, si falla la salud, restaurar el digest A anterior

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 ps

Obté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: 10s

En 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 web

config --images debe mostrar el digest nuevo. pull descarga la imagen sin iniciar contenedores. Si alguna comprobación falla, no reemplaces el archivo activo.

Una etiqueta como app:stable puede pasar de la imagen A a la B; una referencia por digest apunta siempre a la A

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 \
  web

Compose 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.Image coincida 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 \
  web

Reemplaza 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.

Cloud Servers by Donweb

Ya actualizas por digest y sabes volver atrás. Ahora falta el host donde correrlo.
Alojamiento ultra rápido, escalable y con alta disponibilidad.

  • Performance que te sorprenderá
  • Rápida escalabilidad y sin limitaciones
  • Arquitectura de alta disponibilidad
  • Soporte experto y ejecutivos de cuenta
  • Pagos en tu moneda y facturación local

Corre tu stack Compose en un Cloud Server