Push an image to a private Docker registry

Authenticate, tag the intended destination, push and verify the digest, and troubleshoot registry trust and authorization.

Best practices
Illustration of container operations and troubleshooting

Log in to the registry, add a fully qualified repository tag, then push that tag. The image reference determines the destination; logging in does not redirect an unqualified image name to that registry.

docker login registry.example.com
docker tag myapp:1.2 registry.example.com/team/myapp:1.2
docker push registry.example.com/team/myapp:1.2

Use an account or token authorized to push to the intended project. In Harbor, the project usually needs to exist before the push. Cloud registries may require provider-issued credentials with a limited lifetime.

Understand the reference

Adding a tag creates another local reference to the same image; it does not duplicate all its layers or remove the old tag. For a reference with a slash, a first component containing a dot or colon, or equal to localhost, identifies a registry host. An unqualified name such as myapp:1.2 normally targets Docker Hub instead.

After pushing, record the reported digest and inspect the registry entry. Pull the exact repository reference from the intended target environment when checking access. A successful login proves authentication, not push permission, pull permission for every account, or deployment readiness.

Troubleshoot the failure

Failure What to check
Authentication required Registry hostname, credential helper, token validity and login account
Access denied Project/repository scope, robot-account permissions and policy
Repository unknown Correct repository path and required project creation
HTTP response to HTTPS client Wrong endpoint or a registry serving plain HTTP
Certificate verification failure Certificate chain, hostname and trusted private CA

For a registry using a private CA, install the approved CA for Docker rather than disabling verification. On Linux Engine, Docker documents registry-specific trust under /etc/docker/certs.d/<host[:port]>/ca.crt; Docker Desktop has its own certificate integration. Preserve existing daemon configuration when changing trust settings.

An insecure-registries exception allows behavior that weakens transport trust. It is an explicit controlled-environment exception, not the standard remedy for a private certificate. Prefer configuring HTTPS and the correct CA, including on internal networks.

Push from CI

Provide the token through the CI secret mechanism, avoid shell tracing, and use standard input:

set -eu
: "${REGISTRY_TOKEN:?Supply the CI registry token}"
: "${CI_COMMIT_SHORT_SHA:?Supply a commit identifier}"
printf '%s' "$REGISTRY_TOKEN" | docker login registry.example.com \
  --username ci-bot --password-stdin
docker tag myapp:build "registry.example.com/team/myapp:${CI_COMMIT_SHORT_SHA}"
docker push "registry.example.com/team/myapp:${CI_COMMIT_SHORT_SHA}"

This assumes myapp:build was built earlier in the job. A commit tag is useful traceability, but tags remain movable unless the registry enforces immutability; the digest identifies the pushed content. Configure a credential helper where available, since fallback credentials in Docker's config file are encoded, not encrypted.

FAQ

Why is pushing slow? Investigate network throughput, image size and layers. Registries can reuse blobs they already have. Multi-stage builds and removing unnecessary build artifacts can reduce transfer work.

Can the same image go to several registries? Yes. Add each destination tag and push it independently.

Can Harbor block a pull immediately after a successful push? Authorization, scanning policy, quarantine or replication state can affect availability. Check the project's actual policy instead of assuming every pushed artifact is immediately deployable.

See Registry authentication, Image tags and repository names, Docker registry certificate trust.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting