How to Mock a Container Registry in Python

Build an in-memory container registry mock with push, tag listing, and manifest retrieval logic for testing deployment tooling.

Easy Python 3.9+ Aug 9, 2026 Production deployment patterns 14 views 0 copies

Python code

29 lines
Python 3.9+
import json
from collections import defaultdict


class MockRegistry:
    def __init__(self):
        self.repositories = defaultdict(dict)

    def push_image(self, repo: str, tag: str, layers: list[str]) -> None:
        self.repositories[repo][tag] = {
            "layers": layers,
            "size": sum(len(layer) for layer in layers),
        }

    def list_tags(self, repo: str) -> list:
        return sorted(self.repositories.get(repo, {}).keys())

    def manifest(self, repo: str, tag: str) -> dict:
        return self.repositories[repo].get(tag, {})


if __name__ == "__main__":
    registry = MockRegistry()
    registry.push_image("python-app", "v1.0", ["base", "deps", "app"])
    registry.push_image("python-app", "v1.1", ["base", "deps", "app", "fixes"])

    print("Tags:", registry.list_tags("python-app"))
    print("Manifest v1.1:", json.dumps(registry.manifest("python-app", "v1.1"), indent=2))
    print("Missing tag:", registry.manifest("python-app", "nope"))

Output

stdout
Tags: ['v1.0', 'v1.1']
Manifest v1.1: {
  "layers": [
    "base",
    "deps",
    "app",
    "fixes"
  ],
  "size": 16
}
Missing tag: {}

How it works

The MockRegistry class uses a defaultdict(dict) so every repository name automatically maps to an empty nested dictionary, avoiding KeyError on first push. push_image stores the tag as a key with a manifest containing layer names and a computed total size, simulating a real registry API. list_tags returns tags sorted for deterministic test assertions, matching how tools like docker tag list versions. manifest returns {} for missing tags, mirroring the 404-style empty response clients expect. The if __name__ == "__main__" guard lets you demo the behavior directly while keeping the class importable for unit tests.

Common mistakes

  • Using a plain dict instead of defaultdict, which raises KeyError on first push to a new repo.
  • Forgetting to sort tags, causing non-deterministic test output depending on insertion order.
  • Returning None for missing manifests instead of an empty dict, breaking downstream code expecting a dict shape.
  • Hardcoding layer sizes instead of computing them from actual layer data.
  • Using threads without locks — this mock is not thread-safe for concurrent push operations.

Variations

  1. Use a real container registry API client like `docker` or `harborclient` with a local test registry container.
  2. Add `delete_image(repo, tag)` and `repo_exists(repo)` methods to expand test coverage of cleanup workflows.

Real-world use cases

  • Unit-testing deployment scripts that push images and verify tag listings before triggering a rollout.
  • Simulating a registry in CI/CD pipelines to test rollback logic without network access or external dependencies.
  • Developing registry clients or debugging image push/pull code when a real registry is unavailable or too slow.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Production deployment patterns

Related tutorials and quizzes for this topic.