Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(core)!: add support for tc.host and de-prioritise docker:dind #388

Merged
merged 8 commits into from
Mar 1, 2024
24 changes: 12 additions & 12 deletions core/testcontainers/core/container.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,18 +90,18 @@ def get_container_host_ip(self) -> str:
if not host:
return "localhost"

# check testcontainers itself runs inside docker container
if inside_container() and not os.getenv("DOCKER_HOST"):
# If newly spawned container's gateway IP address from the docker
# "bridge" network is equal to detected host address, we should use
# container IP address, otherwise fall back to detected host
# address. Even it's inside container, we need to double check,
# because docker host might be set to docker:dind, usually in CI/CD environment
gateway_ip = self.get_docker_client().gateway_ip(self._container.id)

if gateway_ip == host:
return self.get_docker_client().bridge_ip(self._container.id)
return gateway_ip
# # check testcontainers itself runs inside docker container
# if inside_container() and not os.getenv("DOCKER_HOST") and not host.startswith("http://"):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had to do it, to get things working with Testcontainers Cloud within Codespaces (which runs inside a container). I also thought part of this code duplicate what is done in docker_client.py.

# # If newly spawned container's gateway IP address from the docker
# # "bridge" network is equal to detected host address, we should use
# # container IP address, otherwise fall back to detected host
# # address. Even it's inside container, we need to double check,
# # because docker host might be set to docker:dind, usually in CI/CD environment
# gateway_ip = self.get_docker_client().gateway_ip(self._container.id)

# if gateway_ip == host:
# return self.get_docker_client().bridge_ip(self._container.id)
# return gateway_ip
return host

@wait_container_is_ready()
Expand Down
17 changes: 16 additions & 1 deletion core/testcontainers/core/docker_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,22 @@ class DockerClient:
Thin wrapper around :class:`docker.DockerClient` for a more functional interface.
"""
def __init__(self, **kwargs) -> None:
self.client = docker.from_env(**kwargs)
docker_host = DockerClient.read_docker_host_from_properties()

if docker_host:
print(f"using host {docker_host}")
self.client = docker.DockerClient(base_url=docker_host)
else:
self.client = docker.from_env(**kwargs)

def read_docker_host_from_properties():
try:
with open(os.path.expanduser('~/.testcontainers.properties')) as f:
for line in f:
if line.startswith('tc.host'):
return line.split('=')[1].strip()
except FileNotFoundError:
return None

@ft.wraps(ContainerCollection.run)
def run(self, image: str, command: Union[str, List[str]] = None,
Expand Down