From cbf6d8caeaeb42f3ee78cffe076cc536966e0b6a Mon Sep 17 00:00:00 2001 From: Rajkaran Yadav Date: Sun, 16 Aug 2026 13:10:03 +0530 Subject: [PATCH] feat(config): support docker.socket.override in properties file Add support for reading TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE from ~/.testcontainers.properties via the docker.socket.override property. This enhancement addresses issue #8537, allowing users to configure the Docker socket override path in their properties file instead of requiring the environment variable. This is particularly useful for environments like Colima and Podman where the socket path needs to be configured for IDE test runs. The implementation follows the existing pattern used for docker.client.strategy, checking TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE environment variable first, then falling back to docker.socket.override property from user properties. Empty environment variables are treated as unset to ensure proper fallback behavior, matching the policy used in getEnvVarOrUserProperty. Closes #8537 --- .../testcontainers/DockerClientFactory.java | 2 +- .../utility/TestcontainersConfiguration.java | 26 ++++++++++ .../TestcontainersConfigurationTest.java | 50 +++++++++++++++++++ 3 files changed, 77 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/org/testcontainers/DockerClientFactory.java b/core/src/main/java/org/testcontainers/DockerClientFactory.java index 989aaf36be3..7626925b254 100644 --- a/core/src/main/java/org/testcontainers/DockerClientFactory.java +++ b/core/src/main/java/org/testcontainers/DockerClientFactory.java @@ -164,7 +164,7 @@ public TransportConfig getTransportConfig() { public String getRemoteDockerUnixSocketPath() { DockerClientProviderStrategy strategy = getOrInitializeStrategy(); if (strategy.allowUserOverrides()) { - String dockerSocketOverride = System.getenv("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"); + String dockerSocketOverride = TestcontainersConfiguration.getInstance().getDockerSocketOverride(); if (!StringUtils.isBlank(dockerSocketOverride)) { return dockerSocketOverride; } diff --git a/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java b/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java index 5c80b82ba9c..b22984dd7be 100644 --- a/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java +++ b/core/src/main/java/org/testcontainers/utility/TestcontainersConfiguration.java @@ -224,6 +224,32 @@ public Integer getClientPingTimeout() { return Integer.parseInt(getEnvVarOrProperty("client.ping.timeout", "10")); } + /** + * Gets the Docker socket override path from configuration. + *

+ * This method checks for the Docker socket override in the following order: + *

    + *
  1. {@code TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE} environment variable (if not empty)
  2. + *
  3. {@code docker.socket.override} property from {@code ~/.testcontainers.properties}
  4. + *
  5. {@code DOCKER_SOCKET_OVERRIDE} environment variable (unprefixed)
  6. + *
+ *

+ * + * @return the configured Docker socket override path, or {@code null} if not set + */ + @UnstableAPI + public String getDockerSocketOverride() { + // Special handling similar to docker.client.strategy + // Looks for TESTCONTAINERS_ prefixed env var only + String prefixedEnvVarOverride = environment.get("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE"); + if (prefixedEnvVarOverride != null && !prefixedEnvVarOverride.isEmpty()) { + return prefixedEnvVarOverride; + } + + // looks for unprefixed env var or unprefixed property, or null if not set + return getEnvVarOrUserProperty("docker.socket.override", null); + } + @Nullable @Contract("_, !null, _ -> !null") private String getConfigurable( diff --git a/core/src/test/java/org/testcontainers/utility/TestcontainersConfigurationTest.java b/core/src/test/java/org/testcontainers/utility/TestcontainersConfigurationTest.java index 4e0520af5ba..3f21a13f096 100644 --- a/core/src/test/java/org/testcontainers/utility/TestcontainersConfigurationTest.java +++ b/core/src/test/java/org/testcontainers/utility/TestcontainersConfigurationTest.java @@ -225,6 +225,56 @@ void shouldTrimImageNames() { .isEqualTo("testcontainers/ryuk:0.3.2"); } + @Test + void shouldReadDockerSocketOverrideFromEnvironment() { + assertThat(newConfig().getDockerSocketOverride()).as("no docker socket override by default").isNull(); + + environment.put("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/docker.sock"); + assertThat(newConfig().getDockerSocketOverride()) + .as("docker socket override read from environment variable") + .isEqualTo("/var/run/docker.sock"); + } + + @Test + void shouldReadDockerSocketOverrideFromUserProperties() { + assertThat(newConfig().getDockerSocketOverride()).as("no docker socket override by default").isNull(); + + userProperties.setProperty("docker.socket.override", "/var/run/docker.sock"); + assertThat(newConfig().getDockerSocketOverride()) + .as("docker socket override read from user properties") + .isEqualTo("/var/run/docker.sock"); + } + + @Test + void shouldNotReadDockerSocketOverrideFromClasspathProperties() { + assertThat(newConfig().getDockerSocketOverride()).as("no docker socket override by default").isNull(); + + classpathProperties.setProperty("docker.socket.override", "/var/run/docker.sock"); + assertThat(newConfig().getDockerSocketOverride()) + .as("docker socket override not read from classpath properties") + .isNull(); + } + + @Test + void shouldApplyDockerSocketOverridePrecedenceOrder() { + userProperties.setProperty("docker.socket.override", "/var/run/user.sock"); + environment.put("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", "/var/run/env.sock"); + + assertThat(newConfig().getDockerSocketOverride()) + .as("environment variable takes precedence over user property") + .isEqualTo("/var/run/env.sock"); + } + + @Test + void shouldTreatBlankEnvironmentVariableAsUnset() { + userProperties.setProperty("docker.socket.override", "/var/run/docker.sock"); + environment.put("TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE", ""); + + assertThat(newConfig().getDockerSocketOverride()) + .as("blank environment variable should fall back to user property") + .isEqualTo("/var/run/docker.sock"); + } + private TestcontainersConfiguration newConfig() { return new TestcontainersConfiguration(userProperties, classpathProperties, environment); }