Secure a Docker registry pull-through cache by reviewing its proxy block: set remoteurl deliberately, choose a ttl, treat any upstream credentials as stored on disk and protect that storage, enable delete if you want cleanup, and put authentication in front of the cache itself.
The proxy block
The configuration reference lists these keys.
| Key | Meaning | Note |
|---|---|---|
proxy.remoteurl | The upstream registry, required | Example given is Docker Hub |
proxy.ttl | Cache expiry | Default 168h; 0 disables expiry |
username and password | Credentials for private upstream images | Stored with the cache |
exec | A command and lifetime that supplies credentials | Alternative to static values |
Pushing to a pull-through cache is not supported.
Credentials live in the cache
The configuration docs warn that private repository credentials are stored in the proxy cache's storage, so you must protect access to that cache. The mirror recipe adds that supplying Hub credentials exposes the private images the account can reach through the mirror. If those must stay private, secure the mirror with authentication.
Practical steps: use a read only account at the upstream, scoped to what the cache needs. Prefer the exec form where it fits, so no static secret sits in the config. Keep the cache storage off shared volumes. Rotate the upstream credential when staff who knew it leave.
TTL and what it means
The recipe says tag requests check the remote for a newer version and re-cache it if one exists. The ttl controls how long cached content lives before expiry, and the registry periodically removes old cached content. A longer value keeps builds working through an upstream outage. A shorter one picks up changes, including a pulled bad image, sooner. Neither setting vets the content. It is a cache, not a review.
The daemon side
The recipe says to set registry-mirrors in daemon.json and reload. It also says the daemon supports Docker Hub mirrors only, a cache mirrors one upstream at a time, and the mirror URL must be a domain root with no path. If your builds pull from other registries, they are not covered by this setting.
Docker Hub's fair use limits still apply to the cache's own upstream pulls, which the page notes for team plan service accounts.
Cleanup needs delete
The recipe says cleaning cached content requires delete to be enabled in the registry configuration. Without it, storage grows. See the related notes on garbage collection before you schedule it.
Reading the logs
The recipe warns that some messages marked as errors are informational. Check the level field. For example, level=info with "unknown blob" means the file is being fetched from upstream. Do not alert on those.
Checklist
- TLS and authentication in front of the cache.
- Upstream account scoped and read only.
- Storage access restricted.
- A chosen
ttl. - Delete and a cleanup schedule.
- Clear expectations that a cache does not scan images.
Safeguard's container image scanning can check what the cache has handed your builds, and the free scan is at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen.
Click through the demo and watch how a result ties back to a specific artifact, which is what you want from any registry you run.
Quick check
Are upstream credentials safe in a pull-through cache?
They are stored in the cache's storage, so protect it. The docs say to secure the mirror with authentication if private images must stay private.
Can the cache mirror several upstream registries?
No. One cache instance mirrors a single upstream registry.
Sources
Last reviewed: 19 October 2026.