Contents
Docker Push Tutorial: Push Images to a Registry (--all-tags, docker login)
docker push uploads an image to a registry. You usually set the target name with docker tag first. For Docker Hub, see Docker Hub.
Syntax
docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]
docker push [OPTIONS] NAME[:TAG]
docker login [OPTIONS] [SERVER]
Options
| Option | Description |
|---|---|
-a, --all-tags | Push all tags of an image |
--platform STRING | Push the manifest for the specified platform as a single-platform image; this does not push the image index, so other manifests, including attestations, are not preserved. Format: os[/arch[/variant]], for example, linux/amd64 |
-q, --quiet | Suppress verbose output |
-p, --password STRING | Password or Personal Access Token (PAT); use - to read from stdin |
--password-stdin | Read the password or Personal Access Token (PAT) from stdin |
-u, --username STRING | Username |
If you don't specify a server for docker login, Docker Hub is used by default. The target name format for docker tag is TARGET_IMAGE[:TAG].
Example
The following example uses the local Registry at localhost:5000 and tags alpine:3.23 in the tools/alpine repository.
Create target tags
$ docker tag alpine:3.23 localhost:5000/tools/alpine:3.23
$ docker tag alpine:3.23 localhost:5000/tools/alpine:latest
$ docker images localhost:5000/tools/alpine
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
localhost:5000/tools/alpine:3.23 ff7f0c727dd7 26.6MB 8.21MB
localhost:5000/tools/alpine:latest ff7f0c727dd7 26.6MB 8.21MB
- Both tags point to the same image ID.
- Each target name includes the registry host and port, repository, and tag.
Push one tag and all tags
$ docker push localhost:5000/tools/alpine:3.23
The push refers to repository [localhost:5000/tools/alpine]
5e9b4a97f639: Unavailable
5e9b4a97f639: Pushed
3.23: digest: sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306 size: 1022
Info -> Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:ff7f0c727dd796aa36787bfcd9a64bf35a6ce72a73451b3359fde849b6703d63 -> sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306
$ docker push localhost:5000/tools/alpine:latest
The push refers to repository [localhost:5000/tools/alpine]
5e9b4a97f639: Layer already exists
latest: digest: sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306 size: 1022
Info -> Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:ff7f0c727dd796aa36787bfcd9a64bf35a6ce72a73451b3359fde849b6703d63 -> sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306
$ docker push --all-tags localhost:5000/tools/alpine
The push refers to repository [localhost:5000/tools/alpine]
5e9b4a97f639: Layer already exists
3.23: digest: sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306 size: 1022
5e9b4a97f639: Layer already exists
latest: digest: sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306 size: 1022
Info -> Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:ff7f0c727dd796aa36787bfcd9a64bf35a6ce72a73451b3359fde849b6703d63 -> sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306
Info -> Not all multiplatform-content is present and only the available single-platform image was pushed
sha256:ff7f0c727dd796aa36787bfcd9a64bf35a6ce72a73451b3359fde849b6703d63 -> sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306
- A single-tag push reports a digest. If you push the same layer again, the output shows
Layer already exists. --all-tagspushes both3.23andlatestintools/alpineat once.- Info message:
alpine:3.23is a multi-platform image, but only some platform content is available locally, so only the currently available single-platform image was pushed (the digest changed fromff7f0c…to the single-platform3d6794…). The push succeeded; the tag in the registry simply has one platform. To push a multi-platform image, see Multi-platform images.
Check registry tags and identify errors
$ wget -qO- http://localhost:5000/v2/tools/alpine/tags/list
{"name":"tools/alpine","tags":["3.23","latest"]}
$ docker push localhost:5000/tools/missing:1.0
The push refers to repository [localhost:5000/tools/missing]
tag does not exist: localhost:5000/tools/missing:1.0
$ docker push docker.io/library/alpine:3.23
The push refers to repository [docker.io/library/alpine]
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Unavailable
5e9b4a97f639: Layer already exists
failed commit on ref "manifest-sha256:3d67941fed5ae436b2bb9791cb3f50a252441c7706bbc5b4e738936df8ff8306": server message: insufficient_scope: authorization failed
- The registry tag list confirms that both
3.23andlatestexist. Pushing a local tag that doesn't exist returnstag does not exist. - When pushing
docker.io/library/alpineto Docker Hub, the final error isinsufficient_scope: authorization failed:library/is the namespace for official images, and no one can push to it. - To push to Docker Hub, first run
docker login(see the options in the table above), then tag the image under your account, for example,your-account/alpine:3.23.
Related topics
- Docker Hub: Docker Hub images and repositories
- Images: View local images
- Multi-platform images: Platforms and manifests
- Free up disk space: Remove unused images
Exercises
Exercise: Tag the local alpine:3.23 as localhost:5000/tools/alpine:latest, then push all tags in tools/alpine.
Answer
docker tag alpine:3.23 localhost:5000/tools/alpine:latest
docker push --all-tags localhost:5000/tools/alpine
FAQ
Why add a registry tag before pushing an image?
docker tag creates a target name that points to the source image. The example tags alpine:3.23 as localhost:5000/tools/alpine:3.23, then pushes that name.
Which tags does docker push --all-tags push?
It pushes all tags in the specified repository. In the example, both 3.23 and latest in tools/alpine are pushed.
What should I do if pushing to Docker Hub returns insufficient_scope?
It means you don't have permission to push to this repository. In the example, docker.io/library/alpine is the namespace for official Docker images, where personal accounts cannot push. To push to Docker Hub, run docker login first, then tag the image as your-account/name:tag and push it. See [Push to Docker Hub](/docker/docker-hub/).
Is the single-platform Info message after a successful push an error?
The example reports the tag's digest, then says that only the available single-platform image was pushed. This is an Info message; it does not mean the push failed.
Updated October 26, 2026