Push a Docker Plugin to a Registry with docker plugin push
A single docker plugin push can overwrite a tag someone else already depends on, so treat it like the one-way door it is. This walks through a checked push of a local plugin to Docker Hub or a private registry, using Docker CLI 29.8.1 from package docker-ce-cli 5:29.8.1-1~ubuntu.24.04~noble. Allow about ten minutes, plus whatever time authentication and the upload itself take.
The route
Jump straight to the step you need, or tick off Done means at the end.
You need a local plugin, access to the Docker daemon, a registry repository you can push to, and credentials for that registry.
Warning
This command uploads plugin content to a registry. Check the name and tag carefully before pressing Enter. A successful push changes remote registry state, and there is no undo command for it.
1. Confirm the installed command
Start with the read-only help output, since it confirms the syntax this particular CLI actually supports:
$ docker plugin push --help
Usage: docker plugin push [OPTIONS] PLUGIN[:TAG]
Push a plugin to a registry
The local manpage documents the same form and lists no command-specific options. The argument is a plugin reference, optionally followed by a tag. Do not carry image-push options like --quiet or --all-tags across to this command; they are not part of the installed docker plugin push interface.
2. Find the exact local plugin reference
List plugins before you log in or push anything:
$ docker plugin ls
ID NAME DESCRIPTION ENABLED
PLUGIN_ID EXAMPLE_USER/example:1.0 Example plugin false
Your own output will differ. Use the value in the NAME column, not the ID, and check the registry namespace carefully. A reference like EXAMPLE_USER/example:1.0 targets the example repository under EXAMPLE_USER. Leave off the tag and Docker falls back to the usual latest convention, but an explicit release tag is far easier to review later.
For a machine-readable check, print just the name and reference:
$ docker plugin ls --format '{{.Name}} {{.PluginReference}}'
EXAMPLE_USER/example:1.0 docker.io/EXAMPLE_USER/example:1.0
The reference is host-specific, so treat that sample output as illustration, not something to paste. If the plugin is missing entirely, stop here and create it through a separate, reviewed workflow first. It does not need to be enabled just to publish it: the requirement is that it exists locally and is ready to ship.
3. Authenticate to the destination registry
Docker registry credentials go through docker login. Log in to the registry named by the plugin reference, with an ordinary account that has permission to push to that repository:
$ docker login docker.io
Username: EXAMPLE_USER
Password: [enter a token without displaying it]
Login Succeeded
For a private registry, swap docker.io for its hostname, for example registry.example.net. Keep a password or access token out of the command line entirely: shells expose command arguments through history and process inspection. Prefer a short-lived token scoped to only the repository you need, and check your organisation's credential-helper policy before authenticating on a shared machine.
Checkpoint
A successful login proves Docker accepted the credentials. It does not prove the destination repository exists, or that your account can actually push this particular plugin.
4. Review the exact push command before running it
Set the reference as a shell variable so there is exactly one value to inspect and reuse:
$ PLUGIN_REF='EXAMPLE_USER/example:1.0'
$ printf 'about to push: %s\n' "$PLUGIN_REF"
about to push: EXAMPLE_USER/example:1.0
Swap the placeholder for the reference from your own docker plugin ls output. Check all three parts when present: registry hostname, namespace or account, and tag. A single typo here can target a different repository or throw a confusing authentication error that has nothing to do with your credentials.
This is the step that actually changes something. It needs permission to contact the Docker daemon and network access to the registry. On Linux, that access may come from root or from membership of the configured Docker group. Do not reach for sudo automatically; use whatever access method is already approved for this host, since Docker group membership is effectively privileged access to the daemon.
5. Push, then read the result properly
Once the reference checks out, run it:
$ docker plugin push "$PLUGIN_REF"
The push refers to repository [docker.io/EXAMPLE_USER/example]
1.0: pushed
1.0: digest: sha256:EXAMPLE_DIGEST size: EXAMPLE_SIZE
The progress text and digest are registry-dependent, so do not script against the exact wording above. What matters is an exit status of zero and a completed push. Capture that status straight away if a script needs to branch on it:
$ status=$?
$ printf 'push exit status: %s\n' "$status"
push exit status: 0
A non-zero status means the operation did not complete. Common causes are a missing local plugin, a wrong namespace or tag, an expired login, insufficient repository permission, an unreachable registry, or a registry that does not support plugin distribution at all. Read the first error properly before retrying; retrying a wrong destination just fails again, faster.
6. Verify without touching the local plugin
Inspect the local plugin again once the push succeeds:
$ docker plugin ls --format '{{.Name}} {{.PluginReference}}'
EXAMPLE_USER/example:1.0 docker.io/EXAMPLE_USER/example:1.0
The local listing should still show exactly the same plugin reference; publishing does not enable, disable, remove or reconfigure it. To check the remote side, use the registry's own repository or tag view, or get another authorised Docker host to inspect the reference. Match the exact tag and digest the push reported, not just the repository name.
Recovery
There is no rollback command in docker plugin push. If you published the wrong tag, leave the correct tag in place and follow the registry's own reviewed retention or deletion process. Do not remove the local plugin as a reaction to a remote naming mistake; docker plugin rm changes local state and has nothing to do with undoing a registry upload.
Done means
- Confirmed the syntax: the installed CLI accepts
docker plugin push [OPTIONS] PLUGIN[:TAG]. - Matched the exact reference with
docker plugin lsbefore touching anything. - Authenticated to the intended registry without a token anywhere near the command line.
- Confirmed exit status zero and the intended tag and digest in the push output.
- Left the local plugin unchanged and checked the remote tag through an authorised registry view.