Skip to content

Commit f5df262

Browse files
tcwaltherSergeyPirogov
authored andcommitted
Add support for docker-outside-of-docker (#23)
* Add support for docker-outside-of-docker This commit adds support for running testcontainers inside Docker * Address pep8 issues * reverse update of Pipfile.lock
1 parent c081c18 commit f5df262

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

Dockerfile

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
FROM python:3.6
2+
3+
COPY ./Pipfile* /workspace/
4+
WORKDIR /workspace
5+
6+
RUN pip install pipenv && \
7+
pipenv install --system --dev --deploy
8+
9+
COPY . /workspace

testcontainers/core/container.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from testcontainers.core.docker_client import DockerClient
66
from testcontainers.core.exceptions import ContainerStartException
7-
from testcontainers.core.utils import is_windows
7+
from testcontainers.core.utils import is_windows, inside_container
88

99

1010
class DockerContainer(object):
@@ -59,14 +59,31 @@ def __enter__(self):
5959
def __exit__(self, exc_type, exc_val, exc_tb):
6060
self.stop()
6161

62+
def __del__(self):
63+
"""
64+
Try to remove the container in all circumstances
65+
"""
66+
if self._container is not None:
67+
try:
68+
self.stop()
69+
except: # noqa: E722
70+
pass
71+
6272
def get_container_host_ip(self) -> str:
63-
if is_windows():
73+
# if testcontainers itself runs in docker, get the newly spawned
74+
# container's IP address from the dockder "bridge" network
75+
if inside_container():
76+
return self.get_docker_client().bridge_ip(self._container.id)
77+
elif is_windows():
6478
return "localhost"
6579
else:
6680
return "0.0.0.0"
6781

6882
def get_exposed_port(self, port) -> str:
69-
return self.get_docker_client().port(self._container.id, port)
83+
if inside_container():
84+
return port
85+
else:
86+
return self.get_docker_client().port(self._container.id, port)
7087

7188
def with_command(self, command: str) -> 'DockerContainer':
7289
self._command = command

testcontainers/core/docker_client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,7 @@ def run(self, image: str,
3838

3939
def port(self, container_id, port):
4040
return self.client.api.port(container_id, port)[0]["HostPort"]
41+
42+
def bridge_ip(self, container_id):
43+
container = self.client.api.containers(filters={'id': container_id})[0]
44+
return container['NetworkSettings']['Networks']['bridge']['IPAddress']

testcontainers/core/utils.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import sys
23

34
LINUX = "linux"
@@ -25,3 +26,12 @@ def is_linux():
2526

2627
def is_windows():
2728
return WIN == os_name()
29+
30+
31+
def inside_container():
32+
"""
33+
Returns true if we are running inside a container.
34+
35+
https://github.com/docker/docker/blob/a9fa38b1edf30b23cae3eade0be48b3d4b1de14b/daemon/initlayer/setup_unix.go#L25
36+
"""
37+
return os.path.exists('/.dockerenv')

0 commit comments

Comments
 (0)