testcontainers / testcontainers-python

Testcontainers is a Python library that providing a friendly API to run Docker container. It is designed to create runtime environment to use during your automatic tests.
https://testcontainers-python.readthedocs.io/en/latest/
Apache License 2.0
1.59k stars 290 forks source link

Bug: (windows/wsl/socket-dind) Devcontainers docker-outside-of-docker ConnectionRefusedError: [Errno 111] Connection refused #538

Open yemaney opened 6 months ago

yemaney commented 6 months ago

Describe the bug

A clear and concise description of what the bug is. What did you expect to happen? What happened instead?

Main code exists inside a devcontainer. The host machine (windows) docker is mounted into the container to enable docker-outside-of-docker.

Expected the tests to run.

To Reproduce

Provide a self-contained code snippet that illustrates the bug or unexpected behavior. Ideally, send a Pull Request to illustrate with a test that illustrates the problem.

# tests/test_api_auth.py
from sqlmodel import Session, SQLModel, create_engine, select
from testcontainers.postgres import PostgresContainer

def test_session():

    with PostgresContainer("postgres:16") as postgres:
        DB_URL = postgres.get_connection_url()
        print(f"{DB_URL = }")

        test_engine = create_engine(f"{DB_URL}")

        SQLModel.metadata.create_all(test_engine)
        with Session(test_engine) as session:
            print(session)
$ hatch run test
=================================================================== test session starts ===================================================================
platform linux -- Python 3.12.2, pytest-8.1.1, pluggy-1.4.0
rootdir: /workspaces/microservice-py-docker
configfile: pyproject.toml
plugins: anyio-4.3.0
collected 1 item                                                                                                                                          

tests/test_api_auth.py F                                                                                                                            [100%]

======================================================================== FAILURES =========================================================================
______________________________________________________________________ test_session _______________________________________________________________________

    def test_session():

>       with PostgresContainer("postgres:16") as postgres:

tests/test_api_auth.py:6: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/home/vscode/.local/share/hatch/env/virtual/api/6jr5RRfn/api/lib/python3.12/site-packages/testcontainers/core/container.py:98: in __enter__
    return self.start()
/home/vscode/.local/share/hatch/env/virtual/api/6jr5RRfn/api/lib/python3.12/site-packages/testcontainers/core/generic.py:70: in start
    super().start()
/home/vscode/.local/share/hatch/env/virtual/api/6jr5RRfn/api/lib/python3.12/site-packages/testcontainers/core/container.py:76: in start
    Reaper.get_instance()
/home/vscode/.local/share/hatch/env/virtual/api/6jr5RRfn/api/lib/python3.12/site-packages/testcontainers/core/container.py:175: in get_instance
    Reaper._instance = Reaper._create_instance()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

cls = <class 'testcontainers.core.container.Reaper'>

    @classmethod
    def _create_instance(cls) -> "Reaper":
        logger.debug(f"Creating new Reaper for session: {SESSION_ID}")

        Reaper._container = (
            DockerContainer(c.ryuk_image)
            .with_name(f"testcontainers-ryuk-{SESSION_ID}")
            .with_exposed_ports(8080)
            .with_volume_mapping(c.ryuk_docker_socket, "/var/run/docker.sock", "rw")
            .with_kwargs(privileged=c.ryuk_privileged, auto_remove=True)
            .with_env("RYUK_RECONNECTION_TIMEOUT", c.ryuk_reconnection_timeout)
            .start()
        )
        wait_for_logs(Reaper._container, r".* Started!")

        container_host = Reaper._container.get_container_host_ip()
        container_port = int(Reaper._container.get_exposed_port(8080))

        Reaper._socket = socket()
>       Reaper._socket.connect((container_host, container_port))
E       ConnectionRefusedError: [Errno 111] Connection refused

/home/vscode/.local/share/hatch/env/virtual/api/6jr5RRfn/api/lib/python3.12/site-packages/testcontainers/core/container.py:212: ConnectionRefusedError
------------------------------------------------------------------ Captured stderr call -------------------------------------------------------------------
Pulling image testcontainers/ryuk:0.7.0
Container started: 4544557450bc
Waiting for container <Container: 4544557450bc> with image testcontainers/ryuk:0.7.0 to be ready ...
-------------------------------------------------------------------- Captured log call --------------------------------------------------------------------
INFO     testcontainers.core.container:container.py:77 Pulling image testcontainers/ryuk:0.7.0
INFO     testcontainers.core.container:container.py:89 Container started: 4544557450bc
INFO     testcontainers.core.waiting_utils:waiting_utils.py:52 Waiting for container <Container: 4544557450bc> with image testcontainers/ryuk:0.7.0 to be ready ...
================================================================= short test summary info =================================================================
FAILED tests/test_api_auth.py::test_session - ConnectionRefusedError: [Errno 111] Connection refused
==================================================================== 1 failed in 0.99s ====================================================================

Runtime environment

Provide a summary of your runtime environment. Which operating system, python version, and docker version are you using? What is the version of testcontainers-python you are using? You can run the following commands to get the relevant information.

# Get the operating system information (on a unix os).
$ uname -a
Linux 63a6749e4833 5.15.146.1-microsoft-standard-WSL2 #1 SMP Thu Jan 11 04:09:03 UTC 2024 x86_64 GNU/Linux
# Get the python version.
$ python --version
Python 3.12.2
# Get the docker version and other docker information.
$ docker info
Client:
 Version:    24.0.9-2
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  0.13.1-1
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  2.26.1-1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 6
  Running: 1
  Paused: 0
  Stopped: 5
 Images: 13
 Server Version: 25.0.3
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Using metacopy: false
  Native Overlay Diff: true
  userxattr: false
 Logging Driver: json-file
 Cgroup Driver: cgroupfs
 Cgroup Version: 1
 Plugins:
  Volume: local
  Network: bridge host ipvlan macvlan null overlay
  Log: awslogs fluentd gcplogs gelf journald json-file local splunk syslog
 Swarm: inactive
 Runtimes: runc io.containerd.runc.v2
 Default Runtime: runc
 Init Binary: docker-init
 containerd version: ae07eda36dd25f8a1b98dfbf587313b99c0190bb
 runc version: v1.1.12-0-g51d5e94
 init version: de40ad0
 Security Options:
  seccomp
   Profile: unconfined
 Kernel Version: 5.15.146.1-microsoft-standard-WSL2
 Operating System: Docker Desktop
 OSType: linux
 Architecture: x86_64
 CPUs: 12
 Total Memory: 15.48GiB
 Name: docker-desktop
 ID: 45754d98-604b-4d4d-b9df-e3dafed10e0b
 Docker Root Dir: /var/lib/docker
 Debug Mode: false
 HTTP Proxy: http.docker.internal:3128
 HTTPS Proxy: http.docker.internal:3128
 No Proxy: hubproxy.docker.internal
 Experimental: false
 Insecure Registries:
  hubproxy.docker.internal:5555
  127.0.0.0/8
 Live Restore Enabled: false

WARNING: No blkio throttle.read_bps_device support
WARNING: No blkio throttle.write_bps_device support
WARNING: No blkio throttle.read_iops_device support
WARNING: No blkio throttle.write_iops_device support
WARNING: daemon is not using the default seccomp profile
# Get all python packages.
$ pip freeze
anyio==4.3.0
bcrypt==4.1.2
certifi==2024.2.2
cffi==1.16.0
charset-normalizer==3.3.2
click==8.1.7
coverage==7.4.4
cryptography==42.0.5
dnspython==2.6.1
docker==7.0.0
ecdsa==0.19.0
email_validator==2.1.1
fastapi==0.88.0
greenlet==3.0.3
h11==0.14.0
httpcore==1.0.5
httptools==0.6.1
httpx==0.27.0
idna==3.7
iniconfig==2.0.0
itsdangerous==2.1.2
Jinja2==3.1.3
MarkupSafe==2.1.5
orjson==3.10.0
packaging==24.0
passlib==1.7.4
pika==1.3.2
pluggy==1.4.0
psycopg2==2.9.9
pyasn1==0.6.0
pycparser==2.22
pydantic==1.10.0
pytest==8.1.1
python-dotenv==1.0.1
python-jose==3.3.0
python-multipart==0.0.9
PyYAML==6.0.1
requests==2.31.0
rsa==4.9
six==1.16.0
sniffio==1.3.1
SQLAlchemy==2.0.29
sqlmodel==0.0.13
starlette==0.22.0
testcontainers==4.3.3
typing_extensions==4.11.0
ujson==5.9.0
urllib3==2.2.1
uvicorn==0.29.0
uvloop==0.19.0
watchfiles==0.21.0
websockets==12.0
wrapt==1.16.0

Devcontainer file

{
    "name": "Python 3",
    "image": "mcr.microsoft.com/devcontainers/python:1-3.12-bullseye",
    "features": {
        "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
    }
}