Push a Tagged Docker Image with docker push
Once a registry accepts your tag, other systems can pull it, and you cannot un-ring that bell. This guide takes you through a docker push of one deliberately named image tag, then checks that the local image and registry reference are the ones you meant. Allow about fifteen minutes, assuming the image already exists and you have permission to push to the destination repository.
The route
Jump straight to the step you need, or tick off Done means at the end.
The examples use Docker 29.8.1 from docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble on this machine. docker push is an alias for docker image push.
- It will not: build an image, create a repository or change registry permissions.
- It will: change external state. Read every registry name and tag before you run the final command.
1. Check the installed command
Start with read-only checks. They need no elevated privileges:
$ docker --version
Docker version 29.8.1, build 4a63305
$ docker push --help
Usage: docker push [OPTIONS] NAME[:TAG]
The local manual lists three options: --all-tags (or -a), --platform and --quiet (or -q). The command accepts an image name with an optional tag. If you omit the tag, do not assume that is what you meant. Make the tag explicit in the command you review.
Checkpoint
Confirm the registry hostname, repository path and release tag you intend to publish. Treat a typo in any of these as a publication error, not something to tidy up later.
2. Find the local image
List local images before adding a registry name. This is ordinary, unprivileged inspection:
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
my-service 1.4.0 0123456789ab 2 hours ago 148MB
Your columns and values will differ. Select the exact source image and tag. If it is missing, stop here and build or obtain it through your normal image workflow, because docker push cannot upload an image that is not present locally.
For a narrower check, substitute your real local reference:
$ docker image inspect my-service:1.4.0
[
{
"Id": "sha256:..."
}
]
The full inspection output is longer. Success confirms that Docker knows this local reference. It does not confirm that the destination registry will accept it.
3. Add the registry and repository tag
A local name and a registry-qualified name can refer to the same image. Create the destination tag with docker image tag:
$ docker image tag my-service:1.4.0 registry.example.invalid/team/my-service:1.4.0
$ docker image ls registry.example.invalid/team/my-service:1.4.0
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.example.invalid/team/my-service 1.4.0 0123456789ab 2 hours ago 148MB
Replace registry.example.invalid, team, the repository name and the tag with your own. The tag command changes only local image metadata. It does not contact the registry and does not upload anything.
Recovery
If you created the wrong local tag, remove that tag before retrying:
$ docker image rm registry.example.invalid/team/my-service:1.4.0
Untagged: registry.example.invalid/team/my-service:1.4.0
This removes the named reference, not the underlying image while another tag still points to it. Check the output, and use docker image ls before removing any unqualified tag. Do not use a broad prune command as a shortcut.
4. Authenticate without exposing a secret
Log in to the same registry host before pushing, using the registry's approved account:
$ docker login registry.example.invalid
Username: REGISTRY_USER
Password:
Login Succeeded
The password prompt keeps the secret out of the visible command. Docker stores and retrieves registry credentials according to its client configuration, so review that configuration and your organisation's credential policy before using a shared workstation.
Security warning
Do not paste a password, access token or credential helper secret into a command line.
If login fails, check the hostname, account, network route, certificate trust and repository permission. Repeating docker push will not repair authentication. Elevated privileges are not normally required for login or push. Use sudo only when your Docker installation explicitly requires it, and understand which user's Docker configuration it will use.
5. Push one tag
This is the step that changes remote state. Review the fully qualified reference one last time, then run:
$ docker push registry.example.invalid/team/my-service:1.4.0
The push refers to repository [registry.example.invalid/team/my-service]
...: Pushed
1.4.0: digest: sha256:0123456789abcdef... size: 1234
Layer identifiers, progress lines, digest and size vary. The completion signal to look for is the tag line containing a digest, plus a successful shell status:
$ printf 'push status: %s\n' "$?"
push status: 0
Recovery
Pressing Ctrl-C terminates the push. A failed or interrupted push may leave some layers already stored, but the intended tag is not safe to use until the command completes and you have verified it. Fix the reported problem, then retry the exact reviewed reference.
6. Push every tag deliberately
Use --all-tags only when every local tag under that registry and repository should be published:
$ docker image ls registry.example.invalid/team/my-service
REPOSITORY TAG IMAGE ID
registry.example.invalid/team/my-service 1.4.0 0123456789ab
registry.example.invalid/team/my-service latest 0123456789ab
$ docker push --all-tags registry.example.invalid/team/my-service
This is broader than pushing :1.4.0. Inspect the list first, especially before using it in automation.
Warning
There is no separate undo for tags a registry has already accepted. Removing a local tag with docker image rm does not remove the remote tag. If a remote correction is needed, use the registry's documented retention or deletion controls, with their approvals.
7. Handle platform-specific pushes with care
The installed CLI also accepts --platform os/arch, such as linux/amd64. It pushes a platform-specific manifest as a single-platform image. The image index is not pushed, so other manifests and attestations are not preserved. Use this only when that loss is intentional:
$ docker push --platform linux/amd64 registry.example.invalid/team/my-service:1.4.0
Tip
For a multi-platform image, do not add this option merely to make the command look more explicit. Confirm how the image was built and which manifest form your consumers require. If platform selection is not part of your release plan, push the tagged reference without --platform.
Done means
- Source checked. The local image existed and the destination tag was inspected before upload.
- Login clean. Authentication succeeded for the exact registry host, with no secret in shell history.
- Digest returned. The reviewed, fully qualified tag gave a digest and exit status 0.
- All-tags earned.
--all-tagswas used only after listing every tag it would publish. - Platform flag justified.
--platformwas omitted unless losing the image index and other manifests was intentional. - No undo assumed. You know that deleting a local tag does not undo a tag the registry already accepted.