14 · Container registries & ECR
Your CD pipeline built an image — now it needs a home the cloud can pull from. A container registry (Docker Hub, GHCR, AWS ECR) is that home. Pushing to AWS ECR is a fixed three-step dance: log in, tag the image with the registry's address, then push.
One idea, one try. At your own pace.
LEARN BY DOINGPut your intuition to work3 steps
14 · Container registries & ECR
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.A container registry stores and serves your Docker images so any machine — a teammate's laptop, a CI runner, a cloud server — can `docker pull` the exact image you built. The big options are Docker Hub (public default), GHCR (GitHub-native), and AWS ECR (in your AWS account, next to where you deploy). Pushing to ECR is a fixed three-step flow: `aws ecr get-login-password | docker login` (authenticate), `docker tag` (name the image with the registry's full address), then `docker push`. Tag with the immutable git SHA (or a content digest) so a deployed version is exactly traceable.
Without this:
Without a registry, an image lives only on the machine that built it — the cloud server has no way to get the exact bytes you tested, so you'd be rebuilding (and risking a different result) on every target instead of pulling one verified artifact everywhere.
Lesson 13's CD pipeline ended with docker push — but push to where? The answer is a container registry: a server whose whole job is to store Docker images and hand them out when something runs docker pull. It's to images what GitHub is to git repos — the shared place a built artifact lives so any machine can fetch the exact bytes, not a fresh rebuild.
Three registries cover almost every team:
- Docker Hub — the default public registry (
docker pushwith no host goes here). Great for open base images (python:3.11-slimlives here); free public repos, paid private ones. - GHCR (GitHub Container Registry) —
ghcr.io. Lives next to your code on GitHub, authenticates with the same token your Actions workflow already has. The natural choice when CI/CD is GitHub Actions. - AWS ECR (Elastic Container Registry) —
<account>.dkr.ecr.<region>.amazonaws.com. Lives inside your AWS account, right next to ECS/Beanstalk/SageMaker where you'll deploy. Private by default, IAM-controlled. The default when you deploy on AWS.
The ECR push flow is a fixed three-step dance. ECR is private, so before anything you must authenticate. ECR doesn't take a static password — you fetch a short-lived token and pipe it into docker login:
- Log in.
aws ecr get-login-password --region <r> | docker login --username AWS --password-stdin <registry-url>. TheawsCLI mints a temporary token;--password-stdinfeeds it to Docker without it ever touching your shell history. - Tag. A local image is named like
churn-api:abc123. ECR needs the image named with its full registry address:docker tag churn-api:abc123 <registry-url>/churn-api:abc123. The tag IS the destination address —docker pushreads it to know where to send the bytes. - Push.
docker push <registry-url>/churn-api:abc123uploads the layers. Layers already in the registry are skipped, so repeat pushes are fast.
The order is not interchangeable: you can't push to a registry you haven't logged into, and you can't push an image that isn't tagged with the registry's address. Login → tag → push.
Immutable tags vs digests. A tag like :latest is a movable label — repush and it points somewhere new, so "latest" is a moving target you can't pin a deploy to. Tag with the git SHA instead (:abc123) and you get an immutable, traceable name — that tag always means this build. Even stronger is the digest (@sha256:…), a hash of the image's actual content: pull by digest and you are guaranteed the byte-for-byte identical image, no matter what any tag was later moved to point at. Production deploys reference the SHA tag or the digest, never bare :latest.
The ECR push flow as an ASCII diagram + commands: (1) `aws ecr get-login-password | docker login`, (2) `docker tag` the local image with the registry's full address, (3) `docker push` — tagged with the immutable git SHA, never bare `:latest`.
What is the correct order of steps to push a Docker image to AWS ECR?
- A container registry (Docker Hub, GHCR, AWS ECR) stores built images so any machine can `docker pull` the exact bytes — the handoff point between 'built' and 'running'.
- The ECR push flow is a fixed order: log in (`aws ecr get-login-password | docker login`), `docker tag` with the registry's full address, then `docker push` — login → tag → push.
- Tag with the immutable git SHA (or pin by `@sha256:` digest) for a traceable, reproducible deploy — never reference a movable `:latest` tag in production.
Every cloud-deployed model service pulls its container from a registry — typically ECR when on AWS — tagged with the git SHA, so the running endpoint is traceable to an exact commit and the cloud runs the same image CI verified.
If you remove it: The image would live only on the build machine, so the cloud would have to rebuild from source on every target — risking a different result than the one you tested.