Merged
Conversation
- Add TESTCONTAINERS_HOST_OVERRIDE env var and tc.host.override property to allow explicit host override, bypassing auto-detection - Add TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE env var to override the Docker socket path mounted into Ryuk - Improve gateway fallback by parsing /proc/net/route when bridge gateway inspection fails, instead of falling back to localhost - Improve container detection by checking /proc/1/cgroup as fallback when /.dockerenv doesn't exist (handles more container runtimes) - Add unit tests for route parsing and container detection logic Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
gen_tcp.connect had no timeout (default :infinity), causing an indefinite hang when bridge gateway IP is unreachable due to hairpin NAT issues in DooD environments. Add 5-second connect timeout. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When connecting to Ryuk via docker_hostname:mapped_port fails (common in DooD environments due to hairpin NAT), fall back to connecting via the container's internal IP on its internal port (8080). Both the test runner container and Ryuk are on the same bridge network by default, so direct IP access works reliably. Also extracts try_tcp_connect/2 helper to reduce duplication. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When running inside a container with a shared Docker socket (DooD), the bridge gateway's mapped ports may be unreachable due to hairpin NAT. This change detects that scenario at startup by probing the gateway, and switches to "container networking mode" where: - get_host(container) returns container.ip_address instead of gateway - get_port(container, port) returns the internal port directly All built-in container modules (postgres, mysql, redis, kafka, etc.) now use these DooD-aware APIs, so tests work automatically in both standard and DooD environments without any configuration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PortWaitStrategy now uses get_host(container) and get_port(container) at wait time, overriding the IP set at construction. This fixes Selenium and EMQX containers in DooD. - Update tests that hardcoded 127.0.0.1 or localhost to use the DooD-aware APIs instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Remove unused Container alias from kafka_container_test - Skip host network test in DooD (inherently incompatible since host networking binds to Docker host, not the test container) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
In container_ip mode, containers on custom Docker networks are not reachable from the test container via internal IP (different network). Detect this via the container.network field and fall back to the standard docker_hostname:mapped_port approach for those containers. Also fix unused alias warnings in port_wait_strategy and kafka_container_test. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Kafka: In DooD, clients connect to the container's internal IP so Kafka must advertise on the internal port. Use a BROKER listener name in container mode to avoid advertising the unreachable bridge gateway address. Toxiproxy test: Use get_host(container) instead of get_host() so the API URL uses the correct host in DooD. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tests that require custom Docker networks or have slow container startup in nested Docker are tagged with @tag :dood_limitation and automatically excluded when running inside a container. Affected tests: - Toxiproxy integration (custom network) - Network hostname communication (custom network) - EMQX custom config (slow startup timeout) - Selenium (slow startup timeout) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Kafka needs to advertise an address reachable by clients. In DooD, the container IP is only known after startup. Use after_start to run kafka-configs.sh and update the advertised listener to BROKER://container_ip:internal_port, so KafkaEx clients can resolve the broker address correctly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Kafka's advertised.listeners cannot be dynamically updated to use the container's internal IP after startup. This is a known limitation that testcontainers-java solves with custom startup script injection. Tag these tests for exclusion in DooD environments. Also reverts the kafka-configs.sh after_start approach which doesn't work reliably (not a dynamic config in KRaft mode). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Since Kafka tests are tagged dood_limitation, the DooD-specific listener config is dead code. Revert to original with_kraft_config. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace runtime container check with tag-based exclusion, consistent with all other DooD-incompatible tests. Restore original 127.0.0.1 since this test only runs outside containers. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Member
Author
|
Results from running docker in docker: Results: |
Member
Author
|
@gossi take a look if you have time? |
…-support # Conflicts: # lib/testcontainers.ex
Member
Author
|
also merging this and releasing a 2.1.0-rc1 soon to test both this DinD and docker compose support |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds comprehensive Docker-in-Docker / Docker-outside-of-Docker support so that tests can run inside a container with a shared Docker socket:
Core changes
get_host(container)andget_port(container, port)return the correct host/port based on the connection mode.gateway:mapped_portfails, falls back tocontainer_ip:8080(internal port) since both containers are on the same bridge network.gen_tcp.connectfor Ryuk now has a 5-second timeout instead of infinite, preventing indefinite hangs.Host detection improvements
TESTCONTAINERS_HOST_OVERRIDEenv var /tc.host.overrideproperty to explicitly set the Docker host, bypassing auto-detection (matches testcontainers-java)TESTCONTAINERS_DOCKER_SOCKET_OVERRIDEenv var to override the Docker socket path mounted into Ryuk/proc/net/routefallback: Parses the kernel route table for the default gateway when bridge network inspection fails/proc/1/cgroupfordocker|kubepods|lxc|containerdpatterns when/.dockerenvdoesn't existContainer module updates
All built-in container modules updated to use
get_host(container)/get_port(container, port):postgres, mysql, redis, cassandra, ceph, minio, rabbitmq, emqx, kafka, toxiproxy, selenium
PortWaitStrategyandHttpWaitStrategyalso updated to use the DinD-aware APIs.Custom network handling
Containers on custom Docker networks fall back to
docker_hostname:mapped_portsince the test container can't reach them via internal IP (different network).Test updates
127.0.0.1orlocalhostupdated to useget_host(container)/get_port(container, port)@tag :dood_limitationand auto-excluded when running inside a containerDooD limitations (tagged tests)
These tests are auto-excluded in DooD environments:
Test plan
docker run🤖 Generated with Claude Code