testcontainers-python icon indicating copy to clipboard operation
testcontainers-python copied to clipboard

Bug: Testcontainer fails to fetch server api version on 4.11 but works on 4.10

Open KantiCodes opened this issue 6 months ago • 19 comments

Describe the bug

Hey seems like you released a new minor version 2 hours ago and it has a bug in it.

Bug: Testcontainer fails to fetch server api version on 4.11 but works on 4.10 To Reproduce

Install version 4.11 and try to run the from testcontainers.mssql import DbContainer, SqlServerContainer

>>> from testcontainers.mssql import DbContainer, SqlServerContainer
Traceback (most recent call last):
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    response = self._make_request(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 493, in _make_request
    conn.request(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connection.py", line 445, in request
    self.endheaders()
  File "/home/bartek/.local/share/uv/python/cpython-3.10.8-linux-x86_64-gnu/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/home/bartek/.local/share/uv/python/cpython-3.10.8-linux-x86_64-gnu/lib/python3.10/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/home/bartek/.local/share/uv/python/cpython-3.10.8-linux-x86_64-gnu/lib/python3.10/http/client.py", line 975, in send
    self.connect()
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/transport/unixconn.py", line 26, in connect
    sock.connect(self.unix_socket)
FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/requests/adapters.py", line 667, in send
    resp = conn.urlopen(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 841, in urlopen
    retries = retries.increment(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/util/retry.py", line 474, in increment
    raise reraise(type(error), error, _stacktrace)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/util/util.py", line 38, in reraise
    raise value.with_traceback(tb)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 787, in urlopen
    response = self._make_request(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connectionpool.py", line 493, in _make_request
    conn.request(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/urllib3/connection.py", line 445, in request
    self.endheaders()
  File "/home/bartek/.local/share/uv/python/cpython-3.10.8-linux-x86_64-gnu/lib/python3.10/http/client.py", line 1277, in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
  File "/home/bartek/.local/share/uv/python/cpython-3.10.8-linux-x86_64-gnu/lib/python3.10/http/client.py", line 1037, in _send_output
    self.send(msg)
  File "/home/bartek/.local/share/uv/python/cpython-3.10.8-linux-x86_64-gnu/lib/python3.10/http/client.py", line 975, in send
    self.connect()
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/transport/unixconn.py", line 26, in connect
    sock.connect(self.unix_socket)
urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/api/client.py", line 223, in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/api/daemon.py", line 181, in version
    return self._result(self._get(url), json=True)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/utils/decorators.py", line 44, in inner
    return f(self, *args, **kwargs)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/api/client.py", line 246, in _get
    return self.get(url, **self._set_request_timeout(kwargs))
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/requests/adapters.py", line 682, in send
    raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/testcontainers/mssql/__init__.py", line 4, in <module>
    from testcontainers.core.generic import DbContainer
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/testcontainers/core/generic.py", line 16, in <module>
    from testcontainers.core.container import DockerContainer
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/testcontainers/core/container.py", line 12, in <module>
    from testcontainers.core.config import ConnectionMode
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/testcontainers/core/config.py", line 52, in <module>
    RYUK_DOCKER_SOCKET: str = get_docker_socket()
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/testcontainers/core/config.py", line 36, in get_docker_socket
    client = docker.from_env()
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/client.py", line 94, in from_env
    return cls(
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/client.py", line 45, in __init__
    self.api = APIClient(*args, **kwargs)
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/api/client.py", line 207, in __init__
    self._version = self._retrieve_server_version()
  File "/home/bartek/projects/US/framework/.venv/lib/python3.10/site-packages/docker/api/client.py", line 230, in _retrieve_server_version
    raise DockerException(
docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

Runtime environment

Ubuntu, python 3.10.8

(bartek) ➜  ~ git:(main) ✗ uv pip list
Package            Version
------------------ ---------
certifi            2025.6.15
charset-normalizer 3.4.2
docker             7.1.0
idna               3.10
python-dotenv      1.1.0
requests           2.32.4
testcontainers     4.11.0
typing-extensions  4.14.0
urllib3            2.4.0
wrapt              1.17.2

EDIT:

I took a dig myself to try to find the culprit

kudos to @chbndrhnns to realizing it connects

4.10

testcontainers/core/config.py: 34

  • RYUK_DOCKER_SOCKET: str = environ.get("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/docker.sock")

4.11

testcontainers/core/config.py:52

  • RYUK_DOCKER_SOCKET: str = get_docker_socket()

Where the get_docker_socket connects

KantiCodes avatar Jun 16 '25 12:06 KantiCodes

I think the problem is it tries to connect on import. I find that strange. I have this case for AsyncRedisContainer which imported fine until 4.10. It's fine there because I am able to set a DOCKER_HOST variable and the connection attempt happens at a later point.

chbndrhnns avatar Jun 16 '25 12:06 chbndrhnns

same here, version 4.11 breaks it because some docker API calls already happen during import time

christianplatta1012 avatar Jun 16 '25 15:06 christianplatta1012

does #831 fix?

pip install -U git+https://github.com/testcontainers/testcontainers-python.git@fix/get_docker_socket-on-import

alexanderankin avatar Jun 16 '25 16:06 alexanderankin

if someone can use the above pip command to test it on their end i would appreciate that a lot, would prefer to get a fix out sooner rather than later.

alexanderankin avatar Jun 16 '25 19:06 alexanderankin

When I apply this patch another error occurs (I'm using colima on a Mac M1 to run docker, if this is of any importance):

ERROR         [ 63%]
test setup failed
../.venv/lib/python3.12/site-packages/docker/api/client.py:275: in _raise_for_status
    response.raise_for_status()
../.venv/lib/python3.12/site-packages/requests/models.py:1026: in raise_for_status
    raise HTTPError(http_error_msg, response=self)
E   requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http+docker://localhost/v1.46/containers/b1c542d96232eafec28bf8b2b5d893f0913d559277cb61dfcc33fa731e1b20e6/json

The above exception was the direct cause of the following exception:
conftest.py:355: in postgres_container
    with start_postgres_db_test_container(resources) as postgres:
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/contextlib.py:137: in __enter__
    return next(self.gen)
conftest.py:386: in start_postgres_db_test_container
    with PostgresContainer(
../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:197: in __enter__
    return self.start()
../.venv/lib/python3.12/site-packages/testcontainers/core/generic.py:74: in start
    super().start()
../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:160: in start
    Reaper.get_instance()
../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:263: in get_instance
    Reaper._instance = Reaper._create_instance()
../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:294: in _create_instance
    wait_for_logs(Reaper._container, r".* Started!", timeout=20, raise_on_exit=True)
../.venv/lib/python3.12/site-packages/testcontainers/core/waiting_utils.py:113: in wait_for_logs
    stdout, stderr = container.get_logs()
../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:243: in get_logs
    return self._container.logs(stderr=False), self._container.logs(stdout=False)
../.venv/lib/python3.12/site-packages/docker/models/containers.py:322: in logs
    return self.client.api.logs(self.id, **kwargs)
../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:19: in wrapped
    return f(self, resource_id, *args, **kwargs)
../.venv/lib/python3.12/site-packages/docker/api/container.py:896: in logs
    output = self._get_result(container, stream, res)
../.venv/lib/python3.12/site-packages/docker/api/client.py:483: in _get_result
    return self._get_result_tty(stream, res, self._check_is_tty(container))
../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:19: in wrapped
    return f(self, resource_id, *args, **kwargs)
../.venv/lib/python3.12/site-packages/docker/api/client.py:479: in _check_is_tty
    cont = self.inspect_container(container)
../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:19: in wrapped
    return f(self, resource_id, *args, **kwargs)
../.venv/lib/python3.12/site-packages/docker/api/container.py:793: in inspect_container
    return self._result(
../.venv/lib/python3.12/site-packages/docker/api/client.py:281: in _result
    self._raise_for_status(response)
../.venv/lib/python3.12/site-packages/docker/api/client.py:277: in _raise_for_status
    raise create_api_error_from_http_exception(e) from e
../.venv/lib/python3.12/site-packages/docker/errors.py:39: in create_api_error_from_http_exception
    raise cls(e, response=response, explanation=explanation) from e
E   docker.errors.NotFound: 404 Client Error for http+docker://localhost/v1.46/containers/b1c542d96232eafec28bf8b2b5d893f0913d559277cb61dfcc33fa731e1b20e6/json: Not Found ("No such container: b1c542d96232eafec28bf8b2b5d893f0913d559277cb61dfcc33fa731e1b20e6")

christianplatta1012 avatar Jun 16 '25 19:06 christianplatta1012

This is the code snippet I use to start the container:

@contextmanager
def start_postgres_db_test_container(resources: Path):
    # nasty bug in wrapt that causes PyCharm/IntelliJ  debugger to crash with: ValueError: wrapper has not been initialized
    # see:
    #  https://github.com/GrahamDumpleton/wrapt/issues/257#issuecomment-1902077286
    # https://youtrack.jetbrains.com/issue/PY-25860
    with pytest.MonkeyPatch.context() as patch:
        patch.setattr(decorators, "AdapterWrapper", PatchedAdapterWrapper)

        from testcontainers.postgres import (
            PostgresContainer,  # import must be here to avoid wrapt bug
        )

        # make testcontainers use the docker daemon from colima if it's running on a Mac and colima is installed
        with pytest.MonkeyPatch.context() as mp:
            if colima_mac_setup():
                # make testcontainers use the docker daemon from colima
                mp.setenv(
                    "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE",
                    f"{str(Path.home())}/.colima/default/docker.sock",
                )
                mp.setenv(
                    "DOCKER_HOST",
                    f"unix://{str(Path.home())}/.colima/default/docker.sock",
                )

        
            with PostgresContainer(
                image="postgres:15.5",
                port=5432,
                username="test",
                password="test",
                dbname="test",
            ) as postgres:
                yield postgres
                print(postgres.get_logs())

def colima_mac_setup():
    return (
        os.uname().sysname == "Darwin"
        and (Path.home() / ".colima" / "default" / "docker.sock").exists()
    )

christianplatta1012 avatar Jun 16 '25 19:06 christianplatta1012

ive yankjed the release for now. need to narrow down a root cause besides the fix above then

alexanderankin avatar Jun 16 '25 20:06 alexanderankin

does #831 fix?

pip install -U git+https://github.com/testcontainers/testcontainers-python.git@fix/get_docker_socket-on-import

This solved the import error

KantiCodes avatar Jun 17 '25 07:06 KantiCodes

@christianplatta1012

(Could you please edit your stacktrace so that it is more readable)

Please add from

from testcontainers.core.config import testcontainers_config, get_docker_socket

print(testcontainers_config.ryuk_docker_socket)
print(get_docker_socket())

before the with PostgresContainer and write here what the result is.

Actually the fix(es) should make the

            if colima_mac_setup():
                # make testcontainers use the docker daemon from colima
                mp.setenv(
                    "TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE",
                    f"{str(Path.home())}/.colima/default/docker.sock",
                )
                mp.setenv(
                    "DOCKER_HOST",
                    f"unix://{str(Path.home())}/.colima/default/docker.sock",
                )

unnecessary.

Please run get_docker_socket without the monkeypatch. If this doesn't return the correct host, we need to adopt it for macos.

CarliJoy avatar Jun 17 '25 07:06 CarliJoy

does #831 fix?

pip install -U git+https://github.com/testcontainers/testcontainers-python.git@fix/get_docker_socket-on-import

https://github.com/testcontainers/testcontainers-python/pull/832 is also a a workaround.

GaetanLepage avatar Jun 17 '25 07:06 GaetanLepage

Sorry for the late reply, kids and work kept me busy :-). I've tried to compile a minimal example that works in 4.10 but breaks in 4.11.

My dev setup:

I'm running this on an Apple M1 Pro, Sequoia 15.5 uname -a returns: Darwin S0184554 24.5.0 Darwin Kernel Version 24.5.0: Tue Apr 22 19:54:49 PDT 2025; root:xnu-11417.121.6~2/RELEASE_ARM64_T6000 arm64

colima version:

colima version 0.8.1 git commit: 96598cc5b64e5e9e1e64891642b91edc8ac49d16

runtime: docker arch: aarch64 client: v28.1.1 server: v27.1.1

colima was installed using brew.

docker version:

Client: Docker Engine - Community Version: 28.1.1 API version: 1.46 (downgraded from 1.49) Go version: go1.24.2 Git commit: 4eba377327 Built: Fri Apr 18 09:44:47 2025 OS/Arch: darwin/arm64 Context: colima

Server: Docker Engine - Community Engine: Version: 27.1.1 API version: 1.46 (minimum version 1.24) Go version: go1.21.12 Git commit: cc13f95 Built: Tue Jul 23 20:00:07 2024 OS/Arch: linux/arm64 Experimental: false containerd: Version: 1.7.19 GitCommit: 2bf793ef6dc9a18e00cb12efb64355c2c9d5eb41 runc: Version: 1.7.19 GitCommit: v1.1.13-0-g58aa920 docker-init: Version: 0.19.0 GitCommit: de40ad0


Testcase:

from testcontainers.postgres import PostgresContainer


def test_python_test_containers_4_11():
    in_container_port = 5432
    with PostgresContainer(
            image="postgres:15.5",
            port=in_container_port,
            username="test_user",
            password="test_pw",
            dbname="test_db",
    ) as postgres:

        db_params= {
            "dbname": postgres.dbname,
            "user": postgres.username,
            "password": postgres.password,
            "host": postgres.get_container_host_ip(),
            "port": postgres.get_exposed_port(in_container_port),
        }
        print(db_params)
        print(postgres.get_logs())

When I run this with any testcontainers version (4.10 or 4.11) I get:

docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))


When I run this and add at the beginning:

    os.environ["TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"] = f"{str(Path.home())}/.colima/default/docker.sock"
    os.environ["DOCKER_HOST"] = f"unix://{str(Path.home())}/.colima/default/docker.sock"

then this works with 4.10


When I run this with the yanked 4.11 version, I get the API version error again with the following stack trace


=============================== 1 error in 0.27s ===============================

tests/seotter_tests/debug_test_containers_411.py:None (tests/seotter_tests/debug_test_containers_411.py)
../../.venv/lib/python3.12/site-packages/urllib3/connectionpool.py:787: in urlopen
    response = self._make_request(
../../.venv/lib/python3.12/site-packages/urllib3/connectionpool.py:493: in _make_request
    conn.request(
../../.venv/lib/python3.12/site-packages/urllib3/connection.py:494: in request
    self.endheaders()
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py:1333: in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py:1093: in _send_output
    self.send(msg)
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py:1037: in send
    self.connect()
../../.venv/lib/python3.12/site-packages/docker/transport/unixconn.py:26: in connect
    sock.connect(self.unix_socket)
E   FileNotFoundError: [Errno 2] No such file or directory

During handling of the above exception, another exception occurred:
../../.venv/lib/python3.12/site-packages/requests/adapters.py:667: in send
    resp = conn.urlopen(
../../.venv/lib/python3.12/site-packages/urllib3/connectionpool.py:841: in urlopen
    retries = retries.increment(
../../.venv/lib/python3.12/site-packages/urllib3/util/retry.py:474: in increment
    raise reraise(type(error), error, _stacktrace)
../../.venv/lib/python3.12/site-packages/urllib3/util/util.py:38: in reraise
    raise value.with_traceback(tb)
../../.venv/lib/python3.12/site-packages/urllib3/connectionpool.py:787: in urlopen
    response = self._make_request(
../../.venv/lib/python3.12/site-packages/urllib3/connectionpool.py:493: in _make_request
    conn.request(
../../.venv/lib/python3.12/site-packages/urllib3/connection.py:494: in request
    self.endheaders()
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py:1333: in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py:1093: in _send_output
    self.send(msg)
/opt/homebrew/Cellar/[email protected]/3.12.10/Frameworks/Python.framework/Versions/3.12/lib/python3.12/http/client.py:1037: in send
    self.connect()
../../.venv/lib/python3.12/site-packages/docker/transport/unixconn.py:26: in connect
    sock.connect(self.unix_socket)
E   urllib3.exceptions.ProtocolError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

During handling of the above exception, another exception occurred:
../../.venv/lib/python3.12/site-packages/docker/api/client.py:223: in _retrieve_server_version
    return self.version(api_version=False)["ApiVersion"]
../../.venv/lib/python3.12/site-packages/docker/api/daemon.py:181: in version
    return self._result(self._get(url), json=True)
../../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:44: in inner
    return f(self, *args, **kwargs)
../../.venv/lib/python3.12/site-packages/docker/api/client.py:246: in _get
    return self.get(url, **self._set_request_timeout(kwargs))
../../.venv/lib/python3.12/site-packages/requests/sessions.py:602: in get
    return self.request("GET", url, **kwargs)
../../.venv/lib/python3.12/site-packages/requests/sessions.py:589: in request
    resp = self.send(prep, **send_kwargs)
../../.venv/lib/python3.12/site-packages/requests/sessions.py:703: in send
    r = adapter.send(request, **kwargs)
../../.venv/lib/python3.12/site-packages/requests/adapters.py:682: in send
    raise ConnectionError(err, request=request)
E   requests.exceptions.ConnectionError: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))

The above exception was the direct cause of the following exception:
debug_test_containers_411.py:4: in <module>
    from testcontainers.postgres import PostgresContainer
../../.venv/lib/python3.12/site-packages/testcontainers/postgres/__init__.py:16: in <module>
    from testcontainers.core.generic import DbContainer
../../.venv/lib/python3.12/site-packages/testcontainers/core/generic.py:16: in <module>
    from testcontainers.core.container import DockerContainer
../../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:12: in <module>
    from testcontainers.core.config import ConnectionMode
../../.venv/lib/python3.12/site-packages/testcontainers/core/config.py:52: in <module>
    RYUK_DOCKER_SOCKET: str = get_docker_socket()
../../.venv/lib/python3.12/site-packages/testcontainers/core/config.py:36: in get_docker_socket
    client = docker.from_env()
../../.venv/lib/python3.12/site-packages/docker/client.py:94: in from_env
    return cls(
../../.venv/lib/python3.12/site-packages/docker/client.py:45: in __init__
    self.api = APIClient(*args, **kwargs)
../../.venv/lib/python3.12/site-packages/docker/api/client.py:207: in __init__
    self._version = self._retrieve_server_version()
../../.venv/lib/python3.12/site-packages/docker/api/client.py:230: in _retrieve_server_version
    raise DockerException(
E   docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))
ERROR: found no collectors for /Users/christian/seo/seotter/tests/seotter_tests/debug_test_containers_411.py::test_python_test_containers_4_11

</ details>

When I run this with the @fix/get_docker_socket-on-import version (and setting the two env vars), I get:


tests/seotter_tests/debug_test_containers_411.py:6 (test_python_test_containers_4_11)
../../.venv/lib/python3.12/site-packages/docker/api/client.py:275: in _raise_for_status
    response.raise_for_status()
../../.venv/lib/python3.12/site-packages/requests/models.py:1026: in raise_for_status
    raise HTTPError(http_error_msg, response=self)
E   requests.exceptions.HTTPError: 404 Client Error: Not Found for url: http+docker://localhost/v1.46/containers/3d2f2f0dc57ed62a9239503a45c304d7d7a9eed023b9fe22d193bfe12bd7cc4d/json

The above exception was the direct cause of the following exception:
debug_test_containers_411.py:11: in test_python_test_containers_4_11
    with PostgresContainer(
../../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:197: in __enter__
    return self.start()
../../.venv/lib/python3.12/site-packages/testcontainers/core/generic.py:74: in start
    super().start()
../../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:160: in start
    Reaper.get_instance()
../../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:263: in get_instance
    Reaper._instance = Reaper._create_instance()
../../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:294: in _create_instance
    wait_for_logs(Reaper._container, r".* Started!", timeout=20, raise_on_exit=True)
../../.venv/lib/python3.12/site-packages/testcontainers/core/waiting_utils.py:113: in wait_for_logs
    stdout, stderr = container.get_logs()
../../.venv/lib/python3.12/site-packages/testcontainers/core/container.py:243: in get_logs
    return self._container.logs(stderr=False), self._container.logs(stdout=False)
../../.venv/lib/python3.12/site-packages/docker/models/containers.py:322: in logs
    return self.client.api.logs(self.id, **kwargs)
../../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:19: in wrapped
    return f(self, resource_id, *args, **kwargs)
../../.venv/lib/python3.12/site-packages/docker/api/container.py:896: in logs
    output = self._get_result(container, stream, res)
../../.venv/lib/python3.12/site-packages/docker/api/client.py:483: in _get_result
    return self._get_result_tty(stream, res, self._check_is_tty(container))
../../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:19: in wrapped
    return f(self, resource_id, *args, **kwargs)
../../.venv/lib/python3.12/site-packages/docker/api/client.py:479: in _check_is_tty
    cont = self.inspect_container(container)
../../.venv/lib/python3.12/site-packages/docker/utils/decorators.py:19: in wrapped
    return f(self, resource_id, *args, **kwargs)
../../.venv/lib/python3.12/site-packages/docker/api/container.py:793: in inspect_container
    return self._result(
../../.venv/lib/python3.12/site-packages/docker/api/client.py:281: in _result
    self._raise_for_status(response)
../../.venv/lib/python3.12/site-packages/docker/api/client.py:277: in _raise_for_status
    raise create_api_error_from_http_exception(e) from e
../../.venv/lib/python3.12/site-packages/docker/errors.py:39: in create_api_error_from_http_exception
    raise cls(e, response=response, explanation=explanation) from e
E   docker.errors.NotFound: 404 Client Error for http+docker://localhost/v1.46/containers/3d2f2f0dc57ed62a9239503a45c304d7d7a9eed023b9fe22d193bfe12bd7cc4d/json: Not Found ("No such container: 3d2f2f0dc57ed62a9239503a45c304d7d7a9eed023b9fe22d193bfe12bd7cc4d")

When I run this with the @fix/get_docker_socket-on-import version and don't set any env vars, I get the API error again. When I run

    print(testcontainers_config.ryuk_docker_socket)
    print(get_docker_socket())

with or without env vars I get the same API or 404 errors

christianplatta1012 avatar Jun 23 '25 12:06 christianplatta1012

See if #833 fixes it for you

alexanderankin avatar Jun 23 '25 12:06 alexanderankin

@christianplatta1012

As written

Please run get_docker_socket without the monkeypatch. If this doesn't return the correct host, we need to adopt it for macos.

(Do this for the yanked 4.11 version)

I don't have MacOS to test the docker Socket. But the idea is that get_docker_socket determines the correct docker socket in all circumstances.

Please also post the result of:

import docker

client = docker.from_env()
print(f"{client!r}")
print(f"client.api.base_url}"
print(f"{client.api.get_adapter(client.api.base_url)!r}")

That would help to determine what to do to automatically detect colima intalls of docker.

Btw: Did you follow this Guide to use colima?

You need to set the docker context correctly. That should make setting the TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE unnecessary.

If you use #833 please use

from testcontainers.core import testcontainers_config

testcontainers_config.ryuk_docker_socket = "/home/user/docker.sock"

Instead of os.environ["TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"] (I am not sure if DOCKER_HOST env variable is required if you configured the docker context correctly.

CarliJoy avatar Jun 23 '25 13:06 CarliJoy

4.12.0 will go out this week hopefully, any feedback in the form of yes/no would be suffice for me - ive merged 833 so just let me know if the main branch works for you or not

alexanderankin avatar Jun 23 '25 16:06 alexanderankin

Hi,

Btw: Did you follow this Guide to use colima?

yes, I did and my current context is colima and this works with the docker cli.

I think my problem is related to this docker-py issue: https://github.com/docker/docker-py/issues/3146 docker-py seems to use always the default context regardless of the current active context that is used by the docker cli. This explains why setting the DOCKER_HOST variable to the colima socket resolves the "docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))"

Don't know if testcontainers is willing to work around this issue for Mac users. The bug was opened on Jun 22, 2023 so, don't know if there will be a fix from docker-py anytime soon...

christianplatta1012 avatar Jun 24 '25 08:06 christianplatta1012

Thanks for finding the docker-py bug.

I would advise against hacky workarounds but maybe we find a solution that just works stable detection that works in all circumstances?

What comes when you run docker context ls --format json 2> /dev/null ?

For me this shows the correct context for you as well?

Maybe a solution based on something like this:

def get_docker_contexts() -> tuple[Mapping[str, Any], ...]:
    """
    Return all docker contexts
    """
    # we use docker cli instead of docker-py due to
    # https://github.com/docker/docker-py/issues/3146
    json_strings = subprocess.run(
        ["docker", "context", "ls", "--format", "json"], text=True, capture_output=True, check=True
    ).stdout
    return tuple(json.loads(json_string) for json_string in json_strings.splitlines() if json_string.strip())

Would be okay.

CarliJoy avatar Jun 24 '25 09:06 CarliJoy

Hi, get_docker_contexts returns:

{'Current': True, 'Description': 'colima', 'DockerEndpoint': 'unix:///Users/christian.platta/.colima/default/docker.sock', 'Error': '', 'Name': 'colima'}, 
{'Current': False, 'Description': 'colima [profile=amd64_images]', 'DockerEndpoint': 'unix:///Users/christian.platta/.colima/amd64_images/docker.sock', 'Error': '', 'Name': 'colima-amd64_images'},
 {'Current': False, 'Description': 'Current DOCKER_HOST based configuration', 'DockerEndpoint': 'unix:///var/run/docker.sock', 'Error': '', 'Name': 'default'}

on my system. When the "'Current': True" context is used, it should work as expected

christianplatta1012 avatar Jun 24 '25 12:06 christianplatta1012

I will create a PR once I find time that should detect this and select the proper context. Already have a draft for that.

@christianplatta1012 I kindly ask you again to execute

import docker

client = docker.from_env()
print(f"{client!r}")
print(f"client.api.base_url}"
print(f"{client.api.get_adapter(client.api.base_url)!r}")

And post the results. This helps me to create a proper solution. Which is hard not knowing how systems behave.

CarliJoy avatar Jun 27 '25 14:06 CarliJoy

This snippet

def test_from_env():
    os.environ["DOCKER_HOST"] = f"unix://{str(Path.home())}/.colima/default/docker.sock"

    import docker

    client = docker.from_env()
    print(f"client: {client!r}")
    print(f"client.api.base_url: {client.api.base_url}")
    print(f"client.api.get_adapter(client.api.base_url: {client.api.get_adapter(client.api.base_url)!r}")

with testcontainers version 4.10 returns:

client: <docker.client.DockerClient object at 0x106d67470> client.api.base_url: http+docker://localhost client.api.get_adapter(client.api.base_url: <docker.transport.unixconn.UnixHTTPAdapter object at 0x106d47230>

without the DOCKER_HOST or with version 4.11 in any case it causes the docker.errors.DockerException: Error while fetching server API version: ('Connection aborted.', FileNotFoundError(2, 'No such file or directory'))error

when I do uv pip install -U git+https://github.com/CarliJoy/testcontainers-python.git@a4d9abcc8ae47beb9e4c229243f31731249d7942 to install #833 the same output is printed like with the 4.10 version.

HTH

christianplatta1012 avatar Jun 27 '25 21:06 christianplatta1012

HTH

ok so i guess i am releasing 4.12 tomorrow. if there are any objections - today is the day to voice them

alexanderankin avatar Jul 21 '25 20:07 alexanderankin

we can reopen the issue if i am wrong

alexanderankin avatar Jul 21 '25 20:07 alexanderankin