docker

Docker Registry Explained: Docker Hub, Private Registry & Amazon ECR

Learn how Docker registries work, Docker Hub pull limits, how to run a secure private registry, and how to push, secure and clean up images in Amazon ECR.

By Shubhankar Tripathi • • 5 min read

Docker Registry Explained: Docker Hub, Private Registries, and Amazon ECR


Building a Docker image is only half the job. To run that image on a server, in a CI pipeline or in a Kubernetes cluster, it has to be stored somewhere every machine can reach. That place is a container registry.

Registries look simple from the outside, since you just docker push and docker pull, but the choices behind them matter a great deal in production. Where you store images affects deployment speed, security, cost and reliability. Pull limits on Docker Hub can break a CI pipeline, a self-hosted registry without TLS can expose your images, and an Amazon ECR repository without lifecycle rules quietly accumulates thousands of old images.

This guide explains how registries work, then covers the three options most teams use: Docker Hub, self-hosted private registries (the open-source Distribution registry and Harbor), and Amazon Elastic Container Registry (ECR). You will learn the commands, the security settings and the best practices for each. Details are current as of October 2026 for Docker Engine 29.

Quick Answer


Docker Hub

Self-hosted (Distribution / Harbor)

Amazon ECR

What it is

Docker's public SaaS registry and the default for docker pull

A registry you run on your own servers

AWS's managed private registry

Best for

Public images, open source, base images

Air-gapped, on-premises or full-control environments

Workloads running on AWS

Access control

Docker accounts, organisations and access tokens

You configure it (basic auth, or Harbor RBAC and SSO)

AWS IAM policies and roles

Who operates it

Docker

You

AWS

Login command

docker login

docker login registry.example.com

aws ecr get-login-password ... | docker login ...


What Is a Docker Registry?

A registry is a server that stores container images and serves them over HTTPS using a standard API, the OCI Distribution Specification. Every registry, from Docker Hub to Amazon ECR, speaks the same protocol, which is why the same docker push and docker pull commands work everywhere.

Figure 1: How a container registry stores, receives and serves images

Figure 1: How a container registry stores, receives and serves images

Registry, Repository, Tag and Digest

These four terms are often mixed up. Here is how they relate:

Term

Meaning

Example

Registry

The service that hosts images

docker.io, ghcr.io, 123456789012.dkr.ecr.ap-south-1.amazonaws.com

Repository

A collection of related images, usually versions of one application

library/nginx, bitcodematrix/api

Tag

A human-readable, mutable name for one image in a repository

1.29, 1.4.0, latest

Digest

The SHA-256 hash of an image manifest: an immutable identifier

sha256:9c1f...


How Images Are Stored Inside a Registry

A registry does not store an image as one big file. It stores:

  • Blobs: the compressed filesystem layers and the image configuration, each addressed by its SHA-256 digest.

  • Manifests: small JSON documents listing the configuration blob and layer blobs that make up one image for one platform.

  • Indexes (manifest lists): for multi-platform images, a list of manifests, one per platform such as linux/amd64 and linux/arm64.

  • Tags: pointers from a name such as 1.4.0 to a manifest or index.

Because layers are content-addressed, a registry stores each unique layer once, even if hundreds of images use it. When you push, Docker first asks which layers the registry already has and uploads only the missing ones, then uploads the manifest. When you pull, Docker downloads the index, selects the manifest for your platform, and fetches only the layers you do not already have locally.

How Docker Resolves an Image Name

[registry/][namespace/]repository[:tag][@digest]

 

nginx                         -> docker.io/library/nginx:latest

bitcodematrix/api:1.4.0       -> docker.io/bitcodematrix/api:1.4.0

ghcr.io/acme/web:2.1          -> GitHub Container Registry

registry.example.com:5000/api -> a self-hosted registry on port 5000

If the first part of the name contains a dot (.) or a colon (:), or is localhost, Docker treats it as a registry host name. Otherwise it assumes Docker Hub (docker.io), and for single-word names the library namespace used by Docker Official Images. The tag defaults to latest.

Part 1: Docker Hub

Docker Hub is the world's largest container registry and the default registry for every Docker installation. It hosts several categories of trusted content alongside community images:

Category

Description

Example

Docker Official Images

Curated images maintained with Docker, under the library namespace

nginx, postgres, python

Verified Publisher

Images published by verified commercial vendors

Images from established software companies

Docker-Sponsored Open Source

Images from open-source projects in Docker's sponsorship programme

Popular open-source tools

Docker Hardened Images

Minimal, continuously patched images, free under the Apache 2.0 licence

Pulled from dhi.io after docker login dhi.io

Community images

Anyone can publish; quality and security vary

someuser/sometool


Security: Treat community images with caution. Prefer Official Images, Verified Publisher or Hardened Images, read the Dockerfile where available, and scan every image before using it in production.

Docker Hub Pull Limits

Docker Hub limits how many image pulls each user can make in a 6-hour window. As of October 2026, the limits are:

User type

Pull limit per 6 hours

Unauthenticated

100 per IPv4 address or IPv6 /64 subnet

Docker Personal (free, authenticated)

200

Docker Pro, Team and Business

Unlimited, subject to fair use


A pull is counted for each manifest download; a multi-platform image counts once for each platform pulled. When you exceed the limit, Docker Hub returns HTTP 429 with the error toomanyrequests. Docker revises these limits from time to time, so check the "Docker Hub pull usage and limits" page in Docker's documentation before planning capacity.

Check your remaining pulls without using one (a HEAD request does not count):

TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)

curl -s --head -H "Authorization: Bearer $TOKEN" \

  https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/latest | grep -i ratelimit

The ratelimit-limit and ratelimit-remaining headers show your allowance and what is left, for example 100;w=21600 (100 pulls per 21,600 seconds).

How to avoid hitting the limits:

  • Always log in, especially on CI runners and servers. Many CI systems share one public IP address between thousands of users, so anonymous pulls run out quickly.

  • Cache base images with a pull-through cache, such as a self-hosted registry mirror or an Amazon ECR pull-through cache rule (both covered below).

  • Reuse local images. Use --pull missing (the default) instead of --pull always where freshness is not essential.

Push an Image to Docker Hub

Create an access token in Docker Hub (Account settings, then Personal access tokens) and use it instead of your password. Then log in, tag and push:

echo "$DOCKERHUB_TOKEN" | docker login -u <username> --password-stdin

 

docker build -t <username>/api:1.4.0 .

docker push <username>/api:1.4.0

Repositories on Docker Hub are created automatically on the first push and are public by default. Change visibility in the repository settings if the image must stay private.

Part 2: Private and Self-Hosted Registries

Teams use private registries to keep proprietary images away from the public internet, control access, keep images close to where they run, and avoid public pull limits. You can use a managed service or run your own.

Option

Type

Highlights

Distribution (registry image)

Self-hosted, open source (CNCF)

The reference registry implementation; lightweight, no web interface or user management

Harbor

Self-hosted, open source (CNCF graduated)

Web interface, projects, role-based access, SSO, built-in Trivy scanning, replication, proxy cache, signature policies

GitHub Container Registry

Managed (ghcr.io)

Tight integration with GitHub repositories and Actions

GitLab Container Registry

Managed or self-hosted

Built into GitLab projects and CI

Azure Container Registry, Google Artifact Registry

Managed

Native choices on Azure and Google Cloud

JFrog Artifactory, Sonatype Nexus, Red Hat Quay

Commercial or open-core

Universal artifact management alongside container images

Amazon ECR

Managed

Native choice on AWS (Part 3)


Run a Basic Registry With the Distribution Image

The official registry image runs the CNCF Distribution registry. Version 3 is the current major release (registry:3); its default configuration file is /etc/distribution/config.yml. For a quick local test:

docker run -d --name registry -p 5000:5000 --restart unless-stopped \

  -v registry-data:/var/lib/registry registry:3

 

docker tag nginx:1.29 localhost:5000/nginx:1.29

docker push localhost:5000/nginx:1.29

docker pull localhost:5000/nginx:1.29

Docker allows plain HTTP only for registries on localhost (more precisely, the 127.0.0.0/8 loopback range). For any other host, the registry must use HTTPS.

Do not disable TLS: You may see guides that add a host to insecure-registries in daemon.json to allow plain HTTP. This sends images and credentials unencrypted and allows tampering in transit. Use it only in isolated test labs, never in production.

Secure the Registry With TLS and Authentication

A production-ready minimal setup needs a TLS certificate and authentication. Create a password file with the htpasswd tool (borrowed here from the official httpd image, because the registry image does not include it):

mkdir -p auth certs

docker run --rm --entrypoint htpasswd httpd:2 -Bbn admin "Change-This-Passw0rd" > auth/htpasswd

Place your certificate and private key in certs/ as domain.crt and domain.key (for example from Let's Encrypt or your internal certificate authority), then start the registry:

docker run -d --name registry --restart unless-stopped -p 443:443 \

  -v registry-data:/var/lib/registry \

  -v "$(pwd)/auth":/auth:ro -v "$(pwd)/certs":/certs:ro \

  -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \

  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \

  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \

  -e REGISTRY_AUTH=htpasswd \

  -e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \

  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \

  registry:3

 

docker login registry.example.com

Any setting in the registry's configuration file can be overridden with an environment variable named REGISTRY_ followed by the configuration path in upper case, joined by underscores, as shown above.

If you use a certificate signed by a private certificate authority, give every Docker host that pulls from the registry a copy of the CA certificate:

sudo mkdir -p /etc/docker/certs.d/registry.example.com

sudo cp ca.crt /etc/docker/certs.d/registry.example.com/ca.crt

Store Registry Data in Amazon S3 or Another Object Store

A single server's disk is a single point of failure. The registry can store blobs in object storage instead. For example, with Amazon S3:

-e REGISTRY_STORAGE=s3 \

-e REGISTRY_STORAGE_S3_REGION=ap-south-1 \

-e REGISTRY_STORAGE_S3_BUCKET=my-registry-bucket

Grant access with an IAM instance role on the server rather than access keys. Other supported back ends include Azure Blob Storage, Google Cloud Storage and the local filesystem.

Delete Images and Reclaim Space

Deleting is disabled by default. Enable it with REGISTRY_STORAGE_DELETE_ENABLED=true, delete manifests through the registry API, and then run garbage collection to remove layers no longer referenced by any manifest:

docker exec registry registry garbage-collect /etc/distribution/config.yml

Warning: Do not run garbage collection while images are being pushed; it can delete layers of an upload in progress. Stop pushes first, or put the registry into read-only mode during maintenance. This manual effort is one reason many teams choose Harbor or a managed registry, which provide retention policies and scheduled clean-up.

Use a Registry as a Docker Hub Pull-Through Cache

A pull-through cache (mirror) fetches images from Docker Hub once, stores them, and serves later requests locally. This saves bandwidth and avoids Docker Hub pull limits across many machines. Configure the Distribution registry as a proxy:

docker run -d --name hub-mirror -p 5000:5000 --restart unless-stopped \

  -v mirror-data:/var/lib/registry \

  -e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \

  -e REGISTRY_PROXY_USERNAME=<dockerhub-user> \

  -e REGISTRY_PROXY_PASSWORD=<dockerhub-access-token> \

  registry:3

Then point each Docker host at the mirror in /etc/docker/daemon.json and restart Docker:

{

  "registry-mirrors": ["https://mirror.example.com"]

}

registry-mirrors applies only to images from Docker Hub. Put the mirror behind TLS for any non-local access, as described above.

When to Choose Harbor Instead

The Distribution registry is deliberately minimal. Choose Harbor when you need multiple teams and projects, a web interface, role-based access control with LDAP or OIDC single sign-on, vulnerability scanning with Trivy, policies that block unscanned or unsigned images, replication between registries, quotas and retention policies. Harbor is a graduated CNCF project and is installed with Docker Compose or a Helm chart.

Part 3: Amazon Elastic Container Registry (ECR)

Amazon ECR is AWS's fully managed container registry. It is the natural choice when your containers run on Amazon ECS, AWS Fargate, Amazon EKS, AWS Lambda or EC2, because access is controlled by AWS IAM and images are pulled over the AWS network.

Key ECR Concepts

Concept

Description

Private registry

Every AWS account has one private registry per Region, at <account-id>.dkr.ecr.<region>.amazonaws.com

Repository

Holds the images for one application, for example bitcodematrix/api; settings such as scanning and tag immutability are per repository

Authorisation token

A temporary Docker login password from aws ecr get-login-password, valid for 12 hours

Repository policy

A resource-based policy that can grant other accounts or services access to a repository

Lifecycle policy

Rules that automatically expire old or untagged images

ECR Public

A separate public registry at public.ecr.aws for sharing images publicly


Step 1: Create a Repository

With the AWS CLI configured, create a repository with vulnerability scanning on push and immutable tags (replace the Region with your own):

aws ecr create-repository \

  --repository-name bitcodematrix/api \

  --image-scanning-configuration scanOnPush=true \

  --image-tag-mutability IMMUTABLE \

  --region ap-south-1

Traditionally the repository must exist before you push. Since December 2025, ECR can also create repositories automatically on push, using settings from a repository creation template; set one up if your pipelines push to many repositories.

Step 2: Log In, Tag and Push

ACCOUNT_ID=123456789012

REGION=ap-south-1

REGISTRY=$ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com

 

aws ecr get-login-password --region $REGION | \

  docker login --username AWS --password-stdin $REGISTRY

 

docker build -t $REGISTRY/bitcodematrix/api:1.4.0 .

docker push $REGISTRY/bitcodematrix/api:1.4.0

The username is always the literal value AWS. The IAM identity running these commands needs ecr:GetAuthorizationToken plus push permissions on the repository, such as ecr:InitiateLayerUpload, ecr:UploadLayerPart, ecr:CompleteLayerUpload, ecr:BatchCheckLayerAvailability and ecr:PutImage.

To avoid logging in every 12 hours on developer machines and build servers, install the Amazon ECR Docker Credential Helper and configure it in ~/.docker/config.json. Docker then fetches fresh tokens automatically using your AWS credentials:

{

  "credHelpers": {

    "123456789012.dkr.ecr.ap-south-1.amazonaws.com": "ecr-login"

  }

}

Step 3: Pull Images on AWS Without Passwords

Workloads running on AWS should never store registry passwords. They use IAM roles instead:

Where the image runs

How it authenticates to ECR

Amazon ECS and AWS Fargate

The task execution role (for example with the AmazonECSTaskExecutionRolePolicy managed policy)

Amazon EKS

The node IAM role (for example with the AmazonEC2ContainerRegistryReadOnly managed policy)

EC2 with Docker

An instance profile role plus the ECR credential helper, or aws ecr get-login-password

Another AWS account

A repository policy that grants the other account pull access


Step 4: Clean Up Automatically With Lifecycle Policies

Every CI build pushes a new image, and storage is billed per GB per month. Lifecycle policies keep repositories tidy. This example expires untagged images after 7 days and keeps only the 50 most recent images overall:

{

  "rules": [

    {

      "rulePriority": 1,

      "description": "Expire untagged images after 7 days",

      "selection": {

        "tagStatus": "untagged",

        "countType": "sinceImagePushed",

        "countUnit": "days",

        "countNumber": 7

      },

      "action": { "type": "expire" }

    },

    {

      "rulePriority": 2,

      "description": "Keep only the 50 most recent images",

      "selection": {

        "tagStatus": "any",

        "countType": "imageCountMoreThan",

        "countNumber": 50

      },

      "action": { "type": "expire" }

    }

  ]

}

aws ecr put-lifecycle-policy --repository-name bitcodematrix/api \

  --lifecycle-policy-text file://lifecycle.json --region ap-south-1

A rule with tagStatus set to any must have the highest rulePriority number, so it is evaluated last. Preview the effect safely with aws ecr start-lifecycle-policy-preview before applying a policy to an important repository.

Step 5: Scan Images for Vulnerabilities

Scan type

How it works

Basic scanning

Scans operating system packages when an image is pushed (scanOnPush) or on demand

Enhanced scanning

Powered by Amazon Inspector: scans operating system and programming-language packages, and rescans continuously when new vulnerabilities are published


Configure scanning at the registry level so that every repository is covered, then view results in the console or with:

aws ecr describe-image-scan-findings --repository-name bitcodematrix/api \

  --image-id imageTag=1.4.0 --region ap-south-1

Step 6: Protect Tags With Immutability

With IMMUTABLE tag mutability, pushing a tag that already exists fails with ImageTagAlreadyExistsException, so 1.4.0 can never silently change. If you also publish a moving tag such as latest, use exclusion filters so that only those tags stay mutable:

aws ecr put-image-tag-mutability --repository-name bitcodematrix/api \

  --image-tag-mutability IMMUTABLE_WITH_EXCLUSION \

  --image-tag-mutability-exclusion-filters filterType=WILDCARD,filter=latest \

  --region ap-south-1

Step 7: Cache Public Images With Pull-Through Cache

An ECR pull-through cache rule copies images from an upstream registry into your private registry on first use and keeps them updated. Supported upstreams include Amazon ECR Public, the Kubernetes registry and Quay (no credentials needed), and Docker Hub, GitHub Container Registry, GitLab, Azure Container Registry and Chainguard (credentials stored in AWS Secrets Manager). Cross-account ECR upstreams use an IAM role instead.

For Docker Hub, first store your Docker Hub username and access token in a Secrets Manager secret whose name starts with ecr-pullthroughcache/, in the same account and Region. Then create the rule:

aws ecr create-pull-through-cache-rule \

  --ecr-repository-prefix docker-hub \

  --upstream-registry-url registry-1.docker.io \

  --credential-arn arn:aws:secretsmanager:ap-south-1:123456789012:secret:ecr-pullthroughcache/docker-hub-AbCdEf \

  --region ap-south-1

 

docker pull 123456789012.dkr.ecr.ap-south-1.amazonaws.com/docker-hub/library/nginx:1.29

Note the library/ part for Docker Official Images. Your workloads now pull public base images from ECR inside AWS, avoiding Docker Hub limits and internet egress from private subnets.

Other Useful ECR Features

  • Replication: copy images automatically to other Regions or accounts for disaster recovery and low-latency pulls.

  • Encryption: images are encrypted at rest with Amazon S3-managed keys by default, or with your own AWS KMS key chosen when the repository is created.

  • VPC endpoints: pull images privately from subnets without internet access using interface endpoints for ecr.api and ecr.dkr, plus an S3 gateway endpoint for layer downloads.

  • Signing: sign images with AWS Signer and Notation, or with Sigstore Cosign, and verify signatures before deployment.

ECR charges for storage per GB-month and for data transferred out of the Region. Check the Amazon ECR pricing page for current rates in your Region.

Docker Hub vs Self-Hosted Registry vs Amazon ECR

Criteria

Docker Hub

Self-hosted

Amazon ECR

Setup effort

None

Medium to high

Low

Operations

Managed by Docker

You patch, back up and scale it

Managed by AWS

Authentication

Docker accounts and tokens

htpasswd, or Harbor with LDAP/OIDC

AWS IAM

Pull limits

Yes, on free and anonymous use

Only your own capacity

High service quotas

Vulnerability scanning

Docker Scout

Harbor with Trivy, or external tools

Basic or Amazon Inspector enhanced scanning

Clean-up

Manual or via API

Garbage collection or Harbor retention rules

Lifecycle policies

Air-gapped use

No

Yes

Within AWS only, through VPC endpoints

Typical cost driver

Subscription per user

Servers, storage and engineering time

Storage and data transfer


Rules of thumb: use Docker Hub for public images and as a source of trusted base images; use Amazon ECR for private images that run on AWS; use Harbor or another self-hosted registry for on-premises, air-gapped or multi-cloud environments where you need full control.

Registry Best Practices for Production

  • Never deploy `latest`. Use version tags such as 1.4.0 (often combined with the Git commit SHA), and deploy by digest when you need guaranteed reproducibility.

  • Make release tags immutable, so a tag always refers to the same image.

  • Scan every image on push and continuously, and block deployment of images with critical vulnerabilities.

  • Sign images with Cosign or Notation and verify signatures in your deployment pipeline or admission controller.

  • Use least privilege. CI pipelines need push access to their own repositories only; runtime environments need pull access only.

  • Avoid long-lived passwords. Use access tokens, IAM roles, credential helpers and OIDC federation from CI systems; always log in with --password-stdin.

  • Protect stored credentials. Without a credential helper, docker login stores credentials only base64-encoded in ~/.docker/config.json. Use the credential store of Docker Desktop, pass or the system keychain.

  • Cache external images through a pull-through cache to improve speed and resilience against upstream outages and limits.

  • Clean up automatically with lifecycle or retention policies.

  • Keep the registry close to the workload, in the same cloud Region, to reduce pull time and transfer costs.

Example: Build and Push to ECR From a CI Pipeline

The same steps work in GitHub Actions, GitLab CI, Jenkins or AWS CodeBuild. The pipeline should obtain temporary AWS credentials through OIDC federation or an IAM role rather than stored access keys:

#!/usr/bin/env bash

set -euo pipefail

 

REGISTRY=123456789012.dkr.ecr.ap-south-1.amazonaws.com

IMAGE=$REGISTRY/bitcodematrix/api

VERSION=1.4.0

SHA=$(git rev-parse --short HEAD)

 

aws ecr get-login-password --region ap-south-1 | \

  docker login --username AWS --password-stdin $REGISTRY

 

docker buildx build --platform linux/amd64,linux/arm64 \

  -t $IMAGE:$VERSION -t $IMAGE:$VERSION-$SHA \

  --push .

This produces one multi-platform image under two immutable tags: a release version and a version-plus-commit tag that ties the image to its exact source code.

Troubleshooting Registry Errors

Error message

Likely cause

Fix

toomanyrequests: You have reached your pull rate limit

Docker Hub pull limit exceeded

Log in, use a paid plan, or pull through a cache

unauthorized: authentication required

Not logged in, or the token expired

Run docker login again; for ECR, get a new token (valid 12 hours)

denied: requested access to the resource is denied

Pushing to a namespace you do not own, or missing permissions

Tag the image with your own namespace or registry, and check permissions

no basic auth credentials

No credentials stored for this registry

Log in to the exact registry host name used in the tag

name unknown / RepositoryNotFoundException

The ECR repository does not exist

Create it, or configure create-on-push with a repository creation template

ImageTagAlreadyExistsException

Pushing an existing tag to an immutable ECR repository

Use a new version tag

x509: certificate signed by unknown authority

Self-signed or private CA certificate

Copy the CA to /etc/docker/certs.d/<host>/ca.crt

http: server gave HTTP response to HTTPS client

The registry serves plain HTTP

Enable TLS on the registry

no matching manifest for linux/arm64

The image was not built for your platform

Build a multi-platform image, or pull with --platform

manifest unknown

The tag does not exist in the repository

Check the tag with the registry's console, API or docker buildx imagetools inspect


Frequently Asked Questions

What is the difference between a registry and a repository?

A registry is the service that hosts images, such as Docker Hub or Amazon ECR. A repository is a named collection of related images inside a registry, usually the versions of one application, such as bitcodematrix/api.

Is Docker Hub free?

Yes, for personal use with limits. Free accounts can publish public repositories and pull up to 200 images every 6 hours when logged in; anonymous users get 100 per IP address. Paid plans remove pull limits (subject to fair use) and add features for teams.

Can I use Amazon ECR outside AWS?

Yes. Any Docker host or Kubernetes cluster with network access and valid AWS credentials can pull from ECR. You pay for data transferred out of AWS, so ECR is most cost-effective for workloads running on AWS.

How long does an ECR login last?

The authorisation token from aws ecr get-login-password is valid for 12 hours. The Amazon ECR Docker Credential Helper refreshes it automatically.

Do I need Harbor, or is the basic registry enough?

The basic Distribution registry is enough for a single team that only needs storage with simple authentication. Choose Harbor when you need a web interface, multiple projects, role-based access, single sign-on, scanning, replication or retention policies.

How do I move images from Docker Hub to ECR?

Pull, re-tag and push each image, or copy it directly between registries with docker buildx imagetools create --tag <ecr-image> <dockerhub-image>, which also preserves multi-platform images. For ongoing use of public images, an ECR pull-through cache rule is simpler.

Conclusion and Next Steps

A registry is where your images live between build and run, and it deserves the same care as the rest of your production platform. Docker Hub is the default source of public and trusted base images; a self-hosted Distribution registry or Harbor gives you full control on your own infrastructure; and Amazon ECR provides a managed, IAM-secured registry with scanning, lifecycle policies and pull-through caching for workloads on AWS. Whichever you choose, use immutable version tags, scan and sign images, grant least-privilege access and clean up automatically.

Continue the Docker course with these tutorials on BitCodeMatrix:

  • Docker Architecture Explained — where registries fit alongside the client and daemon

  • Docker Commands Cheat Sheet — docker login, tag, push and pull at a glance

  • Build Smaller, Faster and More Secure Docker Images — shrink what you push

  • Image Tagging Strategy (next in the course) — semantic versions, commit SHAs and digests