From 6a7354b2c0ed4f04b903359fa7ead9487430aeed Mon Sep 17 00:00:00 2001 From: Zach Paden Date: Mon, 26 Jan 2026 19:06:23 -0600 Subject: [PATCH] feat(core): support TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX fixes #808 partially resolve #562, there may be some additional features requested there that this commit does not resolve. Additionally added test cases to check that it's picked up from env into config, and that the config changes the resolved image in DockerContainer --- core/testcontainers/core/config.py | 3 ++- core/testcontainers/core/container.py | 4 ++-- core/tests/test_config.py | 9 ++++++++- core/tests/test_container.py | 23 +++++++++++++++++++++++ 4 files changed, 35 insertions(+), 4 deletions(-) diff --git a/core/testcontainers/core/config.py b/core/testcontainers/core/config.py index cca5d65a..9a59e54c 100644 --- a/core/testcontainers/core/config.py +++ b/core/testcontainers/core/config.py @@ -108,11 +108,12 @@ def _render_bool(self, env_name: str, prop_name: str) -> bool: _docker_auth_config: Optional[str] = field(default_factory=lambda: environ.get("DOCKER_AUTH_CONFIG")) tc_host_override: Optional[str] = environ.get("TC_HOST", environ.get("TESTCONTAINERS_HOST_OVERRIDE")) connection_mode_override: Optional[ConnectionMode] = field(default_factory=get_user_overwritten_connection_mode) - """ https://github.com/testcontainers/testcontainers-go/blob/dd76d1e39c654433a3d80429690d07abcec04424/docker.go#L644 if os env TC_HOST is set, use it """ + hub_image_name_prefix: str = environ.get("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "") + """ Prefix to use for hub image names, e.g. for private registries. """ @property def docker_auth_config(self) -> Optional[str]: diff --git a/core/testcontainers/core/container.py b/core/testcontainers/core/container.py index 4bb4eec4..5b6e1023 100644 --- a/core/testcontainers/core/container.py +++ b/core/testcontainers/core/container.py @@ -1,6 +1,6 @@ import contextlib import sys -from os import PathLike +from os import PathLike, getenv from socket import socket from types import TracebackType from typing import TYPE_CHECKING, Any, Optional, TypedDict, Union, cast @@ -81,7 +81,7 @@ def __init__( for vol in volumes: self.with_volume_mapping(*vol) - self.image = image + self.image = c.hub_image_name_prefix + image self._docker = DockerClient(**(docker_client_kw or {})) self._container: Optional[Container] = None self._command: Optional[Union[str, list[str]]] = command diff --git a/core/tests/test_config.py b/core/tests/test_config.py index 43586031..90261f89 100644 --- a/core/tests/test_config.py +++ b/core/tests/test_config.py @@ -27,7 +27,14 @@ def test_read_tc_properties(monkeypatch: MonkeyPatch) -> None: config = TCC() assert config.tc_properties == {"tc.host": "some_value"} - +def test_hub_image_name_prefix(monkeypatch: MonkeyPatch) -> None: + """ + Ensure that the hub_image_name_prefix configuration variable can be read from the environment + """ + monkeypatch.setenv("TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX", "myregistry.local/") + config = TCC() + assert config.hub_image_name_prefix == "myregistry.local/" + def test_set_tc_properties(monkeypatch: MonkeyPatch) -> None: """ Ensure the configuration file variables can be read if no environment variable is set diff --git a/core/tests/test_container.py b/core/tests/test_container.py index 30b80f79..33fbb58d 100644 --- a/core/tests/test_container.py +++ b/core/tests/test_container.py @@ -3,6 +3,7 @@ from testcontainers.core.container import DockerContainer from testcontainers.core.docker_client import DockerClient from testcontainers.core.config import ConnectionMode +from testcontainers.core.config import testcontainers_config FAKE_ID = "ABC123" @@ -96,3 +97,25 @@ def test_attribute(init_attr, init_value, class_attr, stored_value): """Test that the attributes set through the __init__ function are properly stored.""" with DockerContainer("ubuntu", **{init_attr: init_value}) as container: assert getattr(container, class_attr) == stored_value + + +def test_image_prefix_applied(monkeypatch: pytest.MonkeyPatch) -> None: + """Test that the hub_image_name_prefix is properly applied to the image name.""" + + # Set a prefix + test_prefix = "myregistry.example.com/" + monkeypatch.setattr(testcontainers_config, "hub_image_name_prefix", test_prefix) + + # Create a container and verify the prefix is applied + container = DockerContainer("nginx:latest") + assert container.image == "myregistry.example.com/nginx:latest" + + +def test_image_no_prefix_applied_when_empty(monkeypatch: pytest.MonkeyPatch) -> None: + """Test that when hub_image_name_prefix is empty, no prefix is applied.""" + # Set an empty prefix + monkeypatch.setattr(testcontainers_config, "hub_image_name_prefix", "") + + # Create a container and verify no prefix is applied + container = DockerContainer("nginx:latest") + assert container.image == "nginx:latest"