How do you tag and push an image to a private registry?

6 minintermediateprivate-registrydocker-pushdocker-login

Quick Answer

Build or re-tag the image with the target registry's hostname as a prefix (e.g., myregistry.example.com/myapp:1.0), authenticate to that registry with docker login, and then docker push — Docker resolves which registry to talk to directly from the hostname prefix in the image reference, defaulting to Docker Hub only when no hostname is present at all.

Detailed Answer

The full sequence

docker build -t myapp:1.0 .

docker tag myapp:1.0 myregistry.example.com/myteam/myapp:1.0

docker login myregistry.example.com
# Username: ...
# Password: ...

docker push myregistry.example.com/myteam/myapp:1.0

How Docker knows which registry to talk to

The hostname prefix of the image reference is what determines the target registry — no special flag is needed on docker push itself, since the destination is fully encoded in the tag you give it:

myregistry.example.com/myteam/myapp:1.0
└────────┬────────┘ └───┬───┘ └─┬─┘ └┬┘
     registry host    namespace  repo  tag

docker.io/library/nginx:1.25    (Docker Hub, implicit -- same shape, just defaulted)

If the reference's first segment doesn't look like a hostname (no dot or colon), Docker assumes Docker Hub. If it does look like a hostname — it contains a . or :port, or is explicitly localhost — Docker resolves it as a private registry address instead.

Authenticating with docker login

docker login myregistry.example.com

Credentials are typically cached locally in ~/.docker/config.json — by default in plaintext, unless a credential helper is configured (see the security topic). This means subsequent push/pull operations against that same registry don't require re-authenticating every time within the same session or machine.

Common private registry options

  • Cloud-provider managed registries — AWS ECR, Google Artifact Registry/GCR, Azure Container Registry — tightly integrated with each cloud's own IAM system for authentication, and often the natural choice when already deployed on that cloud.
  • Self-hosted registry software — the open-source Docker Registry (registry:2 image, ironically itself distributed via Docker Hub), or more full-featured options like Harbor (adding vulnerability scanning, RBAC, and replication on top of the base registry functionality).
  • GitHub Container Registry (GHCR), GitLab Container Registry — convenient when your source code and CI/CD already live on that platform, since authentication/permissions can piggyback on the same platform identity.

Why organizations use private registries at all

  • Confidentiality — proprietary application images shouldn't be publicly pullable by anyone on the internet, the way an unauthenticated Docker Hub public repository would be.
  • Access control — a private registry can be scoped with fine-grained permissions (which teams/services can push or pull which images), mirroring the same least-privilege principles covered in the security topic and the Kubernetes stack's RBAC question.
  • Reliability and control — not depending on a third-party public service's availability or rate limits for critical internal image pulls, especially at production scale (see the Docker Hub question's rate-limiting note).
  • Compliance and scanning integration — many private registries integrate directly with vulnerability scanning (see that question) and image signing (see that question), gating what's allowed to be pushed or pulled based on organizational security policy.

Development and testing can reasonably pull common base images straight from Docker Hub. An organization's own proprietary application images belong in a private registry, scoped to only the teams and systems that genuinely need access.