Log In to Docker Registries Without Leaking Tokens

Type your password after docker login --password and it sits in shell history forever, so this guide shows you the way that does not do that.

You will authenticate the Docker CLI to Docker Hub or a private registry in about ten minutes. The examples match Docker Community Edition CLI 29.8.1, installed here as docker-ce-cli version 5:29.8.1-1~ubuntu.24.04~noble.

1. Choose the registry address

Docker Hub is the default when you omit the server. For another registry, pass its hostname and, if needed, its port:

$ docker login registry.example.com:5000

Checkpoint: confirm the address you intend to use before you type a secret anywhere.

2. Log in interactively when a prompt suits you

For Docker Hub, running the command without --username uses Docker's web-based device flow on current CLI releases: follow the displayed URL and one-time code in a browser. To type a username and token at the terminal instead, specify the username:

$ docker login --username YOUR_REGISTRY_USERNAME registry.example.com
Password:

At the password prompt, paste the password or PAT. Nothing is echoed. A successful login normally reports Login Succeeded. Browser prompts can vary by Docker Hub account and CLI release, so treat the command's own URL and code as authoritative.

Warning: never put the real secret after --password on the command line. Shell history, process listings and diagnostic logs can all expose it.

3. Use standard input for scripts and automation

For a non-interactive login, give the username and send the secret through standard input:

printf '%s\n' 'YOUR_REGISTRY_TOKEN' | docker login \
    --username 'YOUR_REGISTRY_USERNAME' \
    --password-stdin \
    registry.example.com

Replace the placeholder token with a value from your secret manager or protected CI variable, and never commit this command with a real token in it. The printf example above is safe as written because the value is visibly a placeholder; in real automation, avoid letting the secret land in a log.

A successful run prints:

Login Succeeded

Docker 27 and later reject non-interactive password options when no username is supplied, so keep --username in scripted logins even when the secret is a PAT. Docker Hub's web-based flow is the one exception, for an interactive command with no username.

Checkpoint: check the exit status straight after login if a script must stop on failure:

if printf '%s\n' "$REGISTRY_TOKEN" | docker login \
    --username "$REGISTRY_USERNAME" --password-stdin "$REGISTRY_HOST"; then
    printf '%s\n' 'Registry authentication succeeded'
else
    status=$?
    printf 'Registry authentication failed with status %s\n' "$status" >&2
    exit "$status"
fi

4. Check where Docker saved the credential

On Linux, Docker keeps client configuration in $HOME/.docker/config.json. With a configured external credential store, the secret goes to that helper instead of sitting in the file. Without one, Docker stores an encoded credential under auths, and base64 encoding is not encryption.

test -r "$HOME/.docker/config.json" && \
    printf '%s\n' 'Docker CLI configuration exists'
grep -E '"(credsStore|credHelpers|auths)"' "$HOME/.docker/config.json"

That second command only shows configuration keys, not the whole file. Never paste the file itself into a ticket or chat: even encoded entries can be usable credentials. If the machine has no suitable credential helper, get one configured before storing a long-lived token.

Configuration is per user. Run docker login with sudo and Docker may write root's configuration instead of yours, which can make a later unprivileged docker pull look unauthenticated. Prefer an unprivileged login when policy allows it, and reach for sudo only when the setup requires it.

5. Verify access without exposing the token

A successful login proves Docker accepted and stored the credential. It does not prove the account can read every repository, so test the actual image or operation you need:

$ docker pull registry.example.com/team/app:stable
stable: Pulling from team/app

What happens next depends on the image and registry. A pull failure can mean missing repository permission, a wrong image name, an unavailable tag, a TLS problem or a registry policy issue, rather than a bad login: keep those causes separate when you troubleshoot.

6. Remove the login when you no longer need it

Logging out removes the stored credential for one registry:

$ docker logout registry.example.com
Removing login credentials for registry.example.com

For Docker Hub, omit the server or use the address shown by your configuration. If you logged in with sudo, log out with sudo too, because root and your ordinary user have separate Docker configurations.

Recovery: logging out fixes a mistaken login or retires a token locally, but it does not revoke the token at the registry. If it may have been exposed, revoke or replace it there as well.

Common traps

Done means