To list images in a Docker registry you query the Registry HTTP API v2 directly, because there is no docker CLI command that enumerates the repositories on a remote registry. People reach for something like docker images expecting it to show what is in a registry, but that command only lists images already pulled to your local daemon. The registry itself is a separate HTTP service, and listing its contents means calling two API endpoints: one for the catalog of repositories, and one for the tags within each repository. Understanding this also matters for security, because an unauthenticated catalog endpoint hands an attacker a map of everything you ship.
Here is how to enumerate a registry properly, and how to make sure yours is not readable by strangers.
Why "docker list images in registry" does not exist
The Docker CLI talks to your local daemon and to registries only for push and pull. It has no verb for "show me everything on that registry." So the common searches, "docker list images in registry" or "docker list containers in registry", are looking for a command that was never built. Containers, in particular, are a runtime concept on a host; a registry stores images, not running containers, so there is nothing to list there at all.
What you actually want is the registry's own catalog. That lives behind the Registry HTTP API v2, which every standard registry (the open-source registry:2, Harbor, and cloud registries with varying auth) implements.
Listing repositories with the catalog endpoint
The catalog endpoint returns the repository names the registry knows about:
curl -s https://registry.example.com/v2/_catalog
A typical response:
{
"repositories": [
"backend/api",
"frontend/web",
"tools/migrator"
]
}
For large registries the catalog is paginated. Use the n parameter to set a page size and follow the Link header for the next page:
curl -s "https://registry.example.com/v2/_catalog?n=100"
If you get a 401, the registry requires authentication, which is what you want in production. Pass a bearer token or basic-auth credentials your registry accepts.
Listing tags for a repository
The catalog gives you repository names, not the individual image versions. To list the tags in a repository, call the tags endpoint with the repository name:
curl -s https://registry.example.com/v2/backend/api/tags/list
Which returns:
{
"name": "backend/api",
"tags": ["1.4.2", "1.5.0", "latest"]
}
Putting it together, a small script that lists every image and its tags looks like this:
#!/usr/bin/env bash
REG="https://registry.example.com"
repos=$(curl -s "$REG/v2/_catalog" | jq -r '.repositories[]')
for repo in $repos; do
tags=$(curl -s "$REG/v2/$repo/tags/list" | jq -r '.tags[]?')
for tag in $tags; do
echo "$repo:$tag"
done
done
To resolve the exact content digest of a specific tag, make a HEAD request for the manifest and read the Docker-Content-Digest header, requesting the v2 manifest media type in the Accept header. That digest is what you should pin in deployments, since tags are mutable and digests are not.
The security angle: an open catalog is a gift to attackers
Here is the part most "list images in docker registry" tutorials skip. The catalog endpoint, if exposed without authentication, tells anyone on the internet the full inventory of your images and every tag. That is reconnaissance gold: it reveals your internal service names, which components you run, and often version numbers that map directly to known CVEs. From there an attacker can pull images (if pull is also open), unpack them, and hunt for embedded secrets and vulnerable dependencies.
Lock it down:
- Require authentication on the registry, including the
/v2/and_catalogendpoints. A registry reachable without credentials should be treated as a finding. - Never expose an internal registry to the public internet. Put it behind a VPN, private network, or authenticating proxy.
- Enable TLS so credentials and image data are not sent in the clear.
- Do not bake secrets into images. Anyone who can pull an image can read every layer; environment files, tokens, and keys in a layer are effectively public to anyone with pull access.
- Scan what the catalog reveals. The version tags you can enumerate are the same versions an attacker maps to CVEs. Scanning your images means you find those issues first. An SCA tool such as Safeguard can inventory the packages inside each image and match them to advisories, which our SCA product does across a registry, and the academy covers registry hardening end to end.
FAQ
How do I list images in a Docker registry?
Query the Registry HTTP API v2. Call GET /v2/_catalog to list repositories, then GET /v2/<repository>/tags/list for the tags in each. There is no single docker CLI command for this, so curl (plus jq for parsing) is the standard approach.
Why does docker have no command to list images in a registry?
The docker CLI communicates with your local daemon and only uses registries for push and pull. Listing remote registry contents is a job for the registry's own HTTP API, not the client. Commands like docker images show only images already pulled locally.
Can I list running containers in a registry?
No. Registries store images, not containers. Containers are a runtime concept that exists on a host running the Docker daemon, so there is nothing container-related to list on a registry. Query the host with docker ps for containers, and the registry API for images.
Is an exposed registry catalog a security risk?
Yes. An unauthenticated _catalog endpoint reveals your full image inventory, internal service names, and version tags, which is valuable reconnaissance for an attacker. Require authentication on all /v2/ endpoints, enable TLS, keep internal registries off the public internet, and never store secrets inside image layers.