What breaks first when a team moves a container pipeline from one cloud to another? It is almost never the image itself. The Dockerfile usually builds fine. What breaks is the login step, the permission model, and the small pile of scripts that assumed one registry’s quirks were universal. That is the real story behind ECR vs ACR vs Artifact Registry, and it is the part most comparison articles skip.
All three services store container images. All three speak the same wire protocol. Yet the day-to-day workflow around them looks surprisingly different, and those differences decide how much work a migration costs. This guide walks through the workflow gaps that matter, with a practical eye on what actually trips people up. (Keyboard foam mod sound differences actually changes)
The shared foundation: same protocol, different front doors
Here is the good news first. Amazon Elastic Container Registry, Azure Container Registry, and Google Artifact Registry all implement the OCI Distribution Specification, the open standard that defines how images are pushed and pulled over HTTP. Because of that shared substrate, the actual transfer of layers is boring and portable. A `docker push` and `docker pull` work against all three once authentication is sorted out. (Open Container Initiative (OCI) specifications)
The trouble is that authentication is never just authentication. Each provider wraps the standard in its own identity system, its own CLI commands, and its own permission vocabulary. Think of the OCI spec as the road and each cloud as a different toll booth with different paperwork. The asphalt is identical; the queue is not.
Amazon ECR: IAM everywhere, and two registries in one name

ECR is tightly welded to AWS Identity and Access Management. Every push and pull is an IAM action, which means permissions are expressed as policies attached to users, roles, or repositories. For teams already living inside AWS, this is genuinely elegant: a CI role can be granted push rights to one repository and nothing else, and the same policy language governs S3, Lambda, and everything else.
The login flow is the part people memorize. You run a command that fetches a password token, then pipe it into your container client’s login. The token expires, so pipelines must regenerate it on every run rather than storing it once. That single detail causes more broken builds than almost anything else, because a cached credential that worked yesterday quietly dies today.
A second wrinkle: ECR actually offers two registries. The private registry uses IAM authentication and is the default for internal workloads. ECR Public is a separate service for anonymous pulls, aimed at sharing images openly. Their auth and permission models differ, and mixing them up in documentation or scripts is a classic mistake. Teams that treat “ECR” as one thing often discover halfway through a project that half their assumptions applied to the other half of the product.
Azure Container Registry: tiers gate the features
ACR takes a different approach. It is a managed private registry organized around SKUs — Basic, Standard, and Premium. Those tiers control storage limits and also which features you can use. Geo-replication and private endpoints sit behind higher tiers, so the registry you pick shapes your architecture before you write a single pipeline line.
Authentication is where the mental model shifts hardest. Instead of a fetched password token, ACR leans on Azure identity. You can log in through the Azure CLI, which exchanges your existing Azure sign-in for a registry token, or you can use service principals and managed identities for automation. For readers who want the full menu, Microsoft’s documentation on ACR authentication methods lays out each option and when it applies.
The practical consequence is that a pipeline migrating from ECR cannot simply swap a URL. The credential plumbing has to be rebuilt around Azure identities, and the permission story moves from IAM policies to Azure role-based access control. That is a real project, not a find-and-replace.
Artifact Registry: one home for more than containers
Google’s entry has the most interesting backstory. Artifact Registry is the successor to the older Container Registry, which was Docker-only. The new service handles Docker images alongside Maven, npm, Python, apt, yum, and Go packages in a single place. That breadth is the point: instead of one registry for containers and another for language packages, teams consolidate. (Docker Docs: What is a registry?)
Google’s overview of Artifact Registry explains the supported formats and the repository model in detail. The workflow implication is significant. If a team also stores npm packages or Python wheels, Artifact Registry can absorb that load, which changes how many credentials and endpoints a pipeline juggles. Fewer moving parts is a genuine win.
The migration angle matters too. Google published a transition guide for moving from the legacy Container Registry to Artifact Registry, and teams still running old image paths need to plan that shift rather than assume the old endpoint lives forever. Anyone maintaining older pipelines should treat the migration as scheduled work, not a background concern.
Side-by-side: how the workflows actually differ
| Workflow step | Amazon ECR | Azure Container Registry | Artifact Registry |
|---|---|---|---|
| Identity system | AWS IAM | Azure AD and RBAC | Google Cloud IAM |
| Typical login | Fetched password token piped to client | CLI login exchanging Azure sign-in | CLI helper configuring Docker credentials |
| Permission granularity | Repository-level IAM policies | Role assignments at registry scope | IAM roles at repository scope |
| Feature gating | Mostly account-level | SKU tiers set feature access | Repository and format choices |
| Non-container formats | Limited | Limited | Broad package support |
| Public sharing | Separate public registry | Public access options | Public repositories possible |
Read that table as a map of where migration effort hides. The identity row is the expensive one. Every row below it inherits from it.
Where teams actually get stuck
First-hand patterns from teams doing this work repeat with almost comic regularity. A few stand out.
The cached credential trap hits ECR users hardest. A token that worked in a local shell gets baked into a CI variable, then expires. The fix is to fetch a fresh token at the start of every job, not to store one.
The identity mismatch bites ACR migrations. Engineers used to IAM policies try to write a policy document for Azure and discover the whole vocabulary is different. Role assignments replace policies, and scope works differently. Budget time for relearning, not translating.
The assumed-endpoint problem catches Artifact Registry newcomers. Old tutorials and internal wikis still reference the legacy registry paths, so copy-paste pipelines point at the wrong host. Auditing every image reference before a migration is unglamorous but saves hours.
The registry-count confusion trips ECR users who forget private and public are distinct services. A script written against one will not authenticate against the other.
There is also a quieter issue: documentation drift. Product pages change, and a pipeline copied from a blog post three years ago may reference commands that have since shifted. Verifying against current official docs before a migration is not busywork; it is the difference between a smooth cutover and a debugging session at midnight.
Practical tips that hold up in real pipelines
A few habits make any of these registries easier to live with.
- Fetch credentials at runtime. Never store a registry password as a long-lived secret when the provider offers short-lived tokens or identity-based login.
- Pin image references by digest in production. Tags move; digests do not.
- Keep registry configuration in one place. A single module or script that handles login and push means a provider switch touches one file, not forty.
- Test the login step in isolation. Most failures happen before the first layer uploads.
- Document which registry tier or repository type you use, and why. Future you will forget.
If your team also manages local-first note tools or writing workflows alongside engineering work, the same principle applies: pick the tool that fits the workflow rather than forcing the workflow around the tool. A comparison of Obsidian vs Logseq local-first notes by workflow makes that point well for knowledge work, and a guide to using Claude in a practical writing workflow shows how tooling choices ripple through daily habits. The container registry decision is the same shape of problem at a bigger scale.
Cost, lock-in, and the honest trade-offs
None of these registries is dramatically cheaper than the others at small scale; the differences show up in egress, storage tiers, and feature gating. ACR’s SKU model makes some costs visible upfront, which some teams appreciate and others find rigid. ECR’s tight IAM integration reduces operational overhead if you are already on AWS. Artifact Registry’s multi-format support can replace several services, which simplifies billing but concentrates dependency on one provider.
Lock-in is the trade-off nobody enjoys discussing. Every registry ties authentication to its cloud’s identity system, so switching means rebuilding credentials, permissions, and pipeline scripts. The OCI standard keeps the images portable; it does not keep the workflow portable. Teams that accept this and design for it, with a single abstraction layer around login and push, pay far less when circumstances change.
Conclusion
The ECR vs ACR vs Artifact Registry question rarely has one right answer. What matters is understanding that the images are portable and the workflows are not. ECR rewards teams already fluent in IAM. ACR rewards teams comfortable with Azure identity and tiered feature planning. Artifact Registry rewards teams that want containers and language packages under one roof. Whichever you choose, treat the login step, the permission model, and the endpoint references as the real migration surface, and verify current documentation before you cut over. The registry is infrastructure; the workflow around it is the product your team actually lives with every day.
FAQ
What is the main difference between ECR, ACR, and Artifact Registry?
All three store container images using the same open standard, but they differ in identity and workflow. ECR uses AWS IAM and fetched login tokens, ACR uses Azure identities and SKU tiers, and Artifact Registry uses Google Cloud IAM while also supporting non-container package formats.
Can I move container images between these registries easily?
The images themselves move easily because all three follow the OCI Distribution Specification. The hard part is authentication and permissions, which must be rebuilt for each provider’s identity system. Plan to change pipeline scripts as well as image URLs.
Why do ECR login tokens expire in CI pipelines?
ECR issues short-lived password tokens that must be regenerated for each pipeline run. Teams that store a token as a long-lived secret find it stops working later. Fetching a fresh token at the start of every job avoids this common failure.
What are ACR SKUs and why do they matter?
ACR offers Basic, Standard, and Premium tiers, and features like geo-replication and private endpoints sit behind higher tiers. The SKU you choose shapes your architecture and cost before you write any pipeline code, so pick it deliberately.
Is Artifact Registry only for container images?
No. Artifact Registry supports Docker images plus Maven, npm, Python, apt, yum, and Go packages in one service. That breadth lets teams consolidate multiple registries and credentials into a single place, which simplifies pipelines.
Should teams still use the older Google Container Registry?
Container Registry is being retired in favor of Artifact Registry, and Google publishes a migration path for moving image references. Teams running older pipelines should plan that transition rather than assume the legacy endpoint remains available indefinitely.


