14 · Registries de contenedores y ECR
Tu pipeline de CD construyó una imagen — ahora necesita un hogar del que la nube pueda hacer pull. Un registry de contenedores (Docker Hub, GHCR, AWS ECR) es ese hogar. Subir a AWS ECR es un baile fijo de tres pasos: hacer login, etiquetar la imagen con la dirección del registry y luego hacer push.
Un registry de contenedores almacena y sirve tus imágenes Docker para que cualquier máquina — la laptop de un compañero, un runner de CI, un servidor en la nube — pueda hacer `docker pull` de la imagen exacta que construiste. Las grandes opciones son Docker Hub (público por defecto), GHCR (nativo de GitHub) y AWS ECR (en tu cuenta de AWS, junto a donde despliegas). Subir a ECR es un flujo fijo de tres pasos: `aws ecr get-login-password | docker login` (autenticar), `docker tag` (nombrar la imagen con la dirección completa del registry) y luego `docker push`. Etiqueta con el SHA inmutable de git (o un digest de contenido) para que una versión desplegada sea exactamente rastreable.
Sin esto:
Sin un registry, una imagen vive solo en la máquina que la construyó — el servidor en la nube no tiene forma de obtener los bytes exactos que probaste, así que estarías reconstruyendo (y arriesgando un resultado distinto) en cada objetivo en lugar de hacer pull de un único artefacto verificado en todas partes.
El pipeline de CD de la lección 13 terminó con docker push — pero push ¿hacia dónde? La respuesta es un registry de contenedores: un servidor cuyo trabajo entero es almacenar imágenes Docker y entregarlas cuando algo hace docker pull. Es a las imágenes lo que GitHub es a los repos de git — el lugar compartido donde vive un artefacto construido para que cualquier máquina pueda traer los bytes exactos, no una reconstrucción nueva.
Tres registries cubren casi a cualquier equipo:
- Docker Hub — el registry público por defecto (
docker pushsin host va aquí). Genial para imágenes base abiertas (python:3.11-slimvive aquí); repos públicos gratis, privados de pago. - GHCR (GitHub Container Registry) —
ghcr.io. Vive junto a tu código en GitHub, se autentica con el mismo token que tu workflow de Actions ya tiene. La elección natural cuando el CI/CD es GitHub Actions. - AWS ECR (Elastic Container Registry) —
<cuenta>.dkr.ecr.<región>.amazonaws.com. Vive dentro de tu cuenta de AWS, justo al lado de ECS/Beanstalk/SageMaker donde desplegarás. Privado por defecto, controlado por IAM. El predeterminado cuando despliegas en AWS.
El flujo de push a ECR es un baile fijo de tres pasos. ECR es privado, así que antes de nada debes autenticarte. ECR no acepta una contraseña estática — obtienes un token de vida corta y lo canalizas a docker login:
- Login.
aws ecr get-login-password --region <r> | docker login --username AWS --password-stdin <url-del-registry>. La CLI deawsacuña un token temporal;--password-stdinse lo pasa a Docker sin que nunca toque el historial de tu shell. - Tag. Una imagen local se llama algo como
churn-api:abc123. ECR la necesita nombrada con su dirección completa de registry:docker tag churn-api:abc123 <url-del-registry>/churn-api:abc123. El tag ES la dirección de destino —docker pushlo lee para saber a dónde enviar los bytes. - Push.
docker push <url-del-registry>/churn-api:abc123sube las capas. Las capas ya presentes en el registry se saltan, así que los pushes repetidos son rápidos.
El orden no es intercambiable: no puedes hacer push a un registry al que no has hecho login, y no puedes hacer push de una imagen que no está etiquetada con la dirección del registry. Login → tag → push.
Tags inmutables vs digests. Un tag como :latest es una etiqueta movible — vuelve a hacer push y apunta a otro lado, así que "latest" es un blanco móvil al que no puedes anclar un despliegue. Etiqueta con el SHA de git en su lugar (:abc123) y obtienes un nombre inmutable y rastreable — ese tag siempre significa este build. Aún más fuerte es el digest (@sha256:…), un hash del contenido real de la imagen: haz pull por digest y tienes garantizada la imagen idéntica byte por byte, sin importar a dónde se haya movido luego cualquier tag. Los despliegues de producción referencian el tag del SHA o el digest, nunca un :latest pelado.
El flujo de push a ECR como diagrama ASCII + comandos: (1) `aws ecr get-login-password | docker login`, (2) `docker tag` la imagen local con la dirección completa del registry, (3) `docker push` — etiquetada con el SHA inmutable de git, nunca `:latest` pelado.
¿Cuál es el orden correcto de pasos para subir una imagen Docker a AWS ECR?
- Un registry de contenedores (Docker Hub, GHCR, AWS ECR) almacena imágenes construidas para que cualquier máquina pueda hacer `docker pull` de los bytes exactos — el punto de relevo entre 'construido' y 'corriendo'.
- El flujo de push a ECR tiene un orden fijo: login (`aws ecr get-login-password | docker login`), `docker tag` con la dirección completa del registry, luego `docker push` — login → tag → push.
- Etiqueta con el SHA inmutable de git (o ancla por digest `@sha256:`) para un despliegue rastreable y reproducible — nunca referencies un tag movible `:latest` en producción.
Todo servicio de modelo desplegado en la nube hace pull de su contenedor desde un registry — típicamente ECR en AWS — etiquetado con el SHA de git, así que el endpoint en marcha es rastreable a un commit exacto y la nube corre la misma imagen que CI verificó.
Si lo quitas: La imagen viviría solo en la máquina de build, así que la nube tendría que reconstruir desde el código en cada objetivo — arriesgando un resultado distinto al que probaste.