Saltar al contenido principal

Registries y ciclo de una imagen

Nuestra imagen funciona en el Docker Engine donde la construimos. Pero otra máquina no posee automáticamente esos bytes. Compartir el código permite reconstruir; distribuir una imagen permite publicar un artefacto construido y recuperarlo desde otros entornos. Un tag es una referencia legible que puede cambiar; cuando necesitamos identificar contenido concreto de forma inequívoca, utilizamos su digest.

código → build → imagen local → registry → pull → otro Engine → contenedor

Git no es un registry​

Git
→ código, Dockerfile e historial del proyecto

registry
→ imágenes construidas y sus referencias

Un registry almacena contenido de imágenes. Dentro encontramos repositorios y referencias:

localhost:5000/dk207-web:1.0
└ registry ───┘ └ repositorio ┘└ tag

En un servicio remoto podría aparecer también una organización: registry.example.com/equipo/web:1.0.

Preparar una imagen propia pequeña​

Crea index.html:

<!doctype html>
<html lang="es">
<meta charset="utf-8">
<title>DK2-07</title>
<h1>Imagen distribuida</h1>
</html>

Y Dockerfile:

FROM nginx:1.27-alpine
COPY index.html /usr/share/nginx/html/index.html

Construye y prueba antes de publicar:

docker build -t dk207-web:1.0 .
docker run --rm -d --name dk207-prueba -p 8070:80 dk207-web:1.0
docker logs dk207-prueba

Abre http://localhost:8070 y después elimina solo el contenedor de prueba:

docker rm -f dk207-prueba

Publicar no sustituye las pruebas.

Registry local de laboratorio​

Ejecuta la imagen oficial con una versión concreta:

docker run -d --name dk207-registry -p 127.0.0.1:5000:5000 registry:3.1.2

Este registry vive en tu equipo y utiliza localhost:5000; la publicación en 127.0.0.1 limita el acceso al propio equipo. El laboratorio local no debe generalizarse como recomendación para registries HTTP remotos ni para producción.

Comprueba estado y logs:

docker ps --filter name=dk207-registry
docker logs dk207-registry

No configuramos un volumen nombrado propio, pero el registry necesita almacenamiento. La imagen oficial declara /var/lib/registry y Docker crea un volumen anónimo para esa ruta. Compruébalo y anota su nombre para la limpieza:

docker inspect dk207-registry --format '{{json .Mounts}}'
docker volume ls

Busca el mount con Destination igual a /var/lib/registry y conserva su Name. Administrar el almacenamiento de un registry en producción queda fuera de alcance.

docker tag identifica; no reconstruye​

docker tag dk207-web:1.0 localhost:5000/dk207-web:1.0
docker image ls dk207-web
docker image ls localhost:5000/dk207-web

Ambas referencias apuntan inicialmente al mismo contenido local. docker tag no ejecuta el Dockerfile ni crea una copia completa.

El nombre con registry indica dónde hará push Docker:

dk207-web:1.0
→ referencia local

localhost:5000/dk207-web:1.0
→ referencia preparada para el registry local

Publicar y recuperar​

docker push localhost:5000/dk207-web:1.0

Revisa la salida: las capas se transfieren o reutilizan y se informa de un digest cuando corresponde.

Para simular un entorno local limpio, elimina únicamente las referencias creadas por este laboratorio y solo después de confirmar el push:

docker image rm localhost:5000/dk207-web:1.0
docker image rm dk207-web:1.0

No utilices prune ni borres imágenes ajenas.

Recupera:

docker pull localhost:5000/dk207-web:1.0
docker run --rm -d --name dk207-recuperada -p 8070:80 localhost:5000/dk207-web:1.0

Comprueba la misma página y elimina el contenedor:

docker rm -f dk207-recuperada

Tags y mutabilidad​

1.0 es una etiqueta legible. Un tag puede moverse para señalar otro contenido si alguien vuelve a publicar con la misma referencia.

latest no significa «más estable», «más reciente según nuestro negocio» ni «probada». Es solo otro tag y no constituye una estrategia de versionado.

Una política puede utilizar 1.0.0, identificadores de commit u otra convención. Debe permitir saber qué artefacto esperamos desplegar.

Prueba la mutabilidad con un tag de experimento, sin sobrescribir 1.0. Publica primero el contenido A que acabas de recuperar:

docker tag localhost:5000/dk207-web:1.0 localhost:5000/dk207-web:demo
docker push localhost:5000/dk207-web:demo

Anota el digest de la salida. En index.html, cambia únicamente el texto del h1 a Imagen distribuida B. Desde la carpeta del Dockerfile, reconstruye y publica con el mismo tag:

docker build -t localhost:5000/dk207-web:demo .
docker push localhost:5000/dk207-web:demo

Anota el nuevo digest y compáralo con el anterior: mismo tag, contenido y digest distintos. Comprueba el cambio visible:

docker run --rm -d --name dk207-demo -p 8070:80 localhost:5000/dk207-web:demo

Abre http://localhost:8070, elimina el contenedor con docker rm -f dk207-demo y restaura el texto original de index.html. La referencia principal 1.0 sigue apuntando al contenido A. Que un tag pueda moverse no significa que debamos sobrescribir versiones publicadas como práctica habitual.

Digest​

El digest identifica contenido concreto de una imagen. Después del push/pull, observa:

docker image inspect localhost:5000/dk207-web:1.0 --format '{{json .RepoDigests}}'

Conceptualmente:

tag    → nombre cómodo que puede moverse
digest → identidad del contenido publicado

También puedes recuperar por digest: ejecuta docker pull seguido de la referencia completa localhost:5000/dk207-web@sha256:… que aparece en RepoDigests, con su valor real y sin las comillas ni los corchetes de la salida. Así seleccionas ese contenido concreto aunque después cambie un tag.

Registry remoto y autenticación​

El registry local del flujo principal no necesita cuenta. En uno remoto o privado puede ser necesario:

docker login <registry>
docker push <registry>/<organizacion>/<repositorio>:<tag>
docker logout <registry>

No escribas contraseñas en Dockerfile, compose.yaml, comandos versionados o imágenes. Sigue el mecanismo seguro proporcionado por el registry y evita compartir la salida de configuración de autenticación.

Privado no significa automáticamente seguro: siguen importando permisos, contenido, actualizaciones y protección de credenciales.

build frente a image en Compose​

Durante desarrollo local:

services:
web:
build: .

Para consumir el artefacto publicado:

services:
web:
image: localhost:5000/dk207-web:1.0
ports:
- "8070:80"
build → este entorno construye
image → este entorno obtiene/usa una referencia

Guarda la variante publicada en un compose.yaml dentro de otra carpeta, sin Dockerfile ni código fuente. Desde esa carpeta, valida y levanta:

docker compose config
docker compose pull
docker compose up -d

Abre http://localhost:8070: debe seguir mostrando el contenido A de 1.0, sin reconstruir. No añadas build por costumbre si la intención es consumir la imagen publicada.

Revisar antes de publicar​

  • prueba comportamiento y healthcheck;
  • comprueba base, tag y usuario;
  • revisa archivos y dependencias;
  • confirma que no contiene .env, tokens, claves ni credenciales;
  • documenta procedencia y versión;
  • decide quién debe poder obtenerla.

Una imagen publicada puede copiarse fuera de tu equipo. Eliminar un secreto en un commit posterior no lo retira de artefactos ya distribuidos. Mover el tag o hacer privado el repositorio tampoco deshace esa exposición.

Errores habituales​

  • confundir repositorio Git y registry;
  • hacer push con una referencia que no incluye el registry correcto;
  • creer que docker tag reconstruye;
  • usar latest como única política;
  • asumir que los tags son inmutables;
  • publicar antes de probar;
  • incluir secretos;
  • considerar un registry privado suficiente protección;
  • reconstruir en cada servidor cuando se pretende distribuir el mismo artefacto;
  • borrar imágenes ajenas para simular otro entorno.

Mini reto: ciclo completo local​

  1. Construye dk207-reto:1.0 y pruébala.
  2. Inicia dk207-registry si no existe.
  3. Etiqueta como localhost:5000/dk207-reto:1.0.
  4. Publica y conserva la evidencia del digest.
  5. Elimina solo las dos referencias del reto.
  6. Recupera mediante pull.
  7. Ejecuta y valida el comportamiento sin rebuild.
  8. Crea un compose.yaml que use solo image:.
  9. Explica tag frente a digest.
  10. Describe dónde encajaría docker login en un registry privado.
  11. Verifica que la imagen no contiene secretos.
  12. Limpia contenedores y referencias dk207-*; conserva o elimina el registry conscientemente.

Para cerrar el laboratorio, ejecuta docker compose down desde la carpeta de su Compose y elimina cualquier contenedor de prueba que hayas dejado activo. Retira solo las referencias del laboratorio:

docker image rm localhost:5000/dk207-web:demo localhost:5000/dk207-web:1.0

Si hiciste el mini reto, retira también sus contenedores y referencias concretas. Antes de eliminar el registry, comprueba de nuevo su mount y el nombre del volumen anónimo anotado:

docker inspect dk207-registry --format '{{json .Mounts}}'
docker rm -f dk207-registry

Después ejecuta docker volume rm seguido únicamente del nombre de ese volumen anónimo. Eliminar el contenedor sin eliminar su volumen puede dejar almacenadas las imágenes del registry. No uses prune: conserva intactos los recursos de otros proyectos.