Push a Tagged Docker Image Without Losing Track of What Ships
You will finish with one deliberately named image tag pushed to a registry, plus a check that the local image and registry reference are the ones you intended. Allow about fifteen minutes, assuming the image already exists and you have permission to push to the destination repository. The examples use Docker 29.8.1 from docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble on this machine.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide uses docker push, an alias for docker image push. It does not build an image, create a repository, or change registry permissions. Pushing is an external state change: once a tag is accepted by the registry, other systems may pull it. 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; 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. A successful command 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. 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 putting a secret in the command
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. Do not paste a password, access token, or credential helper secret into this guide's 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 point 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 useful completion signal is the tag line containing a digest and a successful shell status:
$ printf 'push status: %s\n' "$?"
push status: 0
Pressing Ctrl-C terminates the push operation. A failed or interrupted push may leave some layers already stored, but it does not make the intended tag safe to use until the command completes and you verify it. Retry the exact reviewed reference after fixing the reported problem.
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. There is no separate undo for tags that have already been accepted by a registry. Removing a local tag with docker image rm does not remove the remote tag; use the registry's documented retention or deletion controls, with their approvals, if a remote correction is required.
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
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
- The local image existed and the destination tag was inspected before upload.
- Authentication succeeded for the exact registry host without exposing a secret in shell history.
- The reviewed, fully qualified tag returned a digest and exit status 0.
--all-tagswas used only after listing every tag that it would publish.--platformwas omitted unless losing the image index and other manifests was intentional.- You know that deleting a local tag does not undo a tag already accepted by the registry.