diff --git a/docs/custom_configuration/index.md b/docs/custom_configuration/index.md
index d7e5eb371..b745f2a53 100644
--- a/docs/custom_configuration/index.md
+++ b/docs/custom_configuration/index.md
@@ -4,6 +4,7 @@ Testcontainers supports various configurations to set up your test environment.
| Properties File | Environment Variable | Description | Default |
|---------------------------------|------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------|------------------------------|
+| `docker.api.version` | `DOCKER_API_VERSION` | The Docker API version to use. | `1.44` |
| `docker.config` | `DOCKER_CONFIG` | The directory path that contains the Docker configuration (`config.json`) file. | `~/.docker/` |
| `docker.host` | `DOCKER_HOST` | The Docker daemon socket to connect to. | - |
| `docker.context` | `DOCKER_CONTEXT` | The Docker context to connect to. | - |
diff --git a/src/Testcontainers/Builders/DockerDesktopEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/DockerDesktopEndpointAuthenticationProvider.cs
index 02d164d6f..9411c6b89 100644
--- a/src/Testcontainers/Builders/DockerDesktopEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/DockerDesktopEndpointAuthenticationProvider.cs
@@ -25,6 +25,12 @@ public override bool IsApplicable()
return !RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && DockerEngine != null;
}
+ ///
+ public Version GetDockerApiVersion()
+ {
+ return null;
+ }
+
///
public string GetDockerConfig()
{
diff --git a/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs
index 76d18058a..738050db8 100644
--- a/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/DockerEndpointAuthenticationProvider.cs
@@ -41,7 +41,7 @@ public virtual bool IsAvailable()
{
using (var dockerClientConfiguration = authConfig.GetDockerClientConfiguration(ResourceReaper.DefaultSessionId))
{
- using (var dockerClient = dockerClientConfiguration.CreateClient())
+ using (var dockerClient = dockerClientConfiguration.CreateClient(authConfig.Version))
{
try
{
diff --git a/src/Testcontainers/Builders/TestcontainersEndpointAuthenticationProvider.cs b/src/Testcontainers/Builders/TestcontainersEndpointAuthenticationProvider.cs
index 04335eb00..4e4e9780e 100644
--- a/src/Testcontainers/Builders/TestcontainersEndpointAuthenticationProvider.cs
+++ b/src/Testcontainers/Builders/TestcontainersEndpointAuthenticationProvider.cs
@@ -57,6 +57,12 @@ public override IDockerEndpointAuthenticationConfiguration GetAuthConfig()
return new DockerEndpointAuthenticationConfiguration(_dockerEngine);
}
+ ///
+ public Version GetDockerApiVersion()
+ {
+ return _customConfiguration.GetDockerApiVersion();
+ }
+
///
public string GetDockerConfig()
{
diff --git a/src/Testcontainers/Clients/DockerApiClient.cs b/src/Testcontainers/Clients/DockerApiClient.cs
index 927bb397a..d2cc9dedd 100644
--- a/src/Testcontainers/Clients/DockerApiClient.cs
+++ b/src/Testcontainers/Clients/DockerApiClient.cs
@@ -134,7 +134,7 @@ private static IDockerClient GetDockerClient(Guid sessionId, IDockerEndpointAuth
{
using (var dockerClientConfiguration = dockerEndpointAuthConfig.GetDockerClientConfiguration(sessionId))
{
- return dockerClientConfiguration.CreateClient();
+ return dockerClientConfiguration.CreateClient(dockerEndpointAuthConfig.Version);
}
}
}
diff --git a/src/Testcontainers/Configurations/AuthConfigs/DockerEndpointAuthenticationConfiguration.cs b/src/Testcontainers/Configurations/AuthConfigs/DockerEndpointAuthenticationConfiguration.cs
index 94a0103fa..57c22671a 100644
--- a/src/Testcontainers/Configurations/AuthConfigs/DockerEndpointAuthenticationConfiguration.cs
+++ b/src/Testcontainers/Configurations/AuthConfigs/DockerEndpointAuthenticationConfiguration.cs
@@ -10,6 +10,9 @@ namespace DotNet.Testcontainers.Configurations
[PublicAPI]
public readonly struct DockerEndpointAuthenticationConfiguration : IDockerEndpointAuthenticationConfiguration
{
+ // https://github.com/moby/moby/releases/tag/docker-v29.0.0.
+ private static readonly Version DockerEngineApi = EnvironmentConfiguration.Instance.GetDockerApiVersion() ?? PropertiesFileConfiguration.Instance.GetDockerApiVersion() ?? new Version(1, 44);
+
// Since the static `TestcontainersSettings` class holds the detected container
// runtime information from the auto-discovery mechanism, we can't add a static
// `NamedPipeConnectionTimeout` property to it because that would create a
@@ -30,6 +33,9 @@ public DockerEndpointAuthenticationConfiguration(Uri endpoint, Credentials crede
Credentials = credentials;
}
+ ///
+ public Version Version => DockerEngineApi;
+
///
public Uri Endpoint { get; }
diff --git a/src/Testcontainers/Configurations/AuthConfigs/IDockerEndpointAuthenticationConfiguration.cs b/src/Testcontainers/Configurations/AuthConfigs/IDockerEndpointAuthenticationConfiguration.cs
index b303ce4a6..cafcf2277 100644
--- a/src/Testcontainers/Configurations/AuthConfigs/IDockerEndpointAuthenticationConfiguration.cs
+++ b/src/Testcontainers/Configurations/AuthConfigs/IDockerEndpointAuthenticationConfiguration.cs
@@ -10,6 +10,12 @@ namespace DotNet.Testcontainers.Configurations
[PublicAPI]
public interface IDockerEndpointAuthenticationConfiguration
{
+ ///
+ /// Gets the Docker API version.
+ ///
+ [CanBeNull]
+ Version Version { get; }
+
///
/// Gets the Docker API endpoint.
///
diff --git a/src/Testcontainers/Configurations/CustomConfiguration.cs b/src/Testcontainers/Configurations/CustomConfiguration.cs
index 81c79c003..eed39241c 100644
--- a/src/Testcontainers/Configurations/CustomConfiguration.cs
+++ b/src/Testcontainers/Configurations/CustomConfiguration.cs
@@ -15,6 +15,11 @@ protected CustomConfiguration(IReadOnlyDictionary properties)
_properties = properties;
}
+ protected virtual Version GetDockerApiVersion(string propertyName)
+ {
+ return _properties.TryGetValue(propertyName, out var propertyValue) && !string.IsNullOrEmpty(propertyValue) && Version.TryParse(propertyValue, out var dockerApiVersion) ? dockerApiVersion : null;
+ }
+
protected virtual string GetDockerConfig(string propertyName)
{
return GetPropertyValue(propertyName);
diff --git a/src/Testcontainers/Configurations/EnvironmentConfiguration.cs b/src/Testcontainers/Configurations/EnvironmentConfiguration.cs
index 7a2f9b9c3..c33c62a43 100644
--- a/src/Testcontainers/Configurations/EnvironmentConfiguration.cs
+++ b/src/Testcontainers/Configurations/EnvironmentConfiguration.cs
@@ -10,6 +10,8 @@ namespace DotNet.Testcontainers.Configurations
///
internal class EnvironmentConfiguration : CustomConfiguration, ICustomConfiguration
{
+ private const string DockerApiVersion = "DOCKER_API_VERSION";
+
private const string DockerConfig = "DOCKER_CONFIG";
private const string DockerHost = "DOCKER_HOST";
@@ -54,11 +56,12 @@ static EnvironmentConfiguration()
public EnvironmentConfiguration()
: base(new[]
{
- DockerAuthConfig,
- DockerCertPath,
+ DockerApiVersion,
DockerConfig,
DockerHost,
DockerContext,
+ DockerAuthConfig,
+ DockerCertPath,
DockerTls,
DockerTlsVerify,
DockerHostOverride,
@@ -82,6 +85,12 @@ public EnvironmentConfiguration()
public static ICustomConfiguration Instance { get; }
= new EnvironmentConfiguration();
+ ///
+ public Version GetDockerApiVersion()
+ {
+ return GetDockerApiVersion(DockerApiVersion);
+ }
+
///
public string GetDockerConfig()
{
diff --git a/src/Testcontainers/Configurations/ICustomConfiguration.cs b/src/Testcontainers/Configurations/ICustomConfiguration.cs
index a9964cac4..57e63aa27 100644
--- a/src/Testcontainers/Configurations/ICustomConfiguration.cs
+++ b/src/Testcontainers/Configurations/ICustomConfiguration.cs
@@ -10,6 +10,14 @@ namespace DotNet.Testcontainers.Configurations
///
internal interface ICustomConfiguration
{
+ ///
+ /// Gets the Docker API version custom configuration.
+ ///
+ /// The Docker API version custom configuration.
+ /// https://dotnet.testcontainers.org/custom_configuration/.
+ [CanBeNull]
+ Version GetDockerApiVersion();
+
///
/// Gets the Docker config custom configuration.
///
diff --git a/src/Testcontainers/Configurations/PropertiesFileConfiguration.cs b/src/Testcontainers/Configurations/PropertiesFileConfiguration.cs
index 7ae19fe46..a4412010e 100644
--- a/src/Testcontainers/Configurations/PropertiesFileConfiguration.cs
+++ b/src/Testcontainers/Configurations/PropertiesFileConfiguration.cs
@@ -56,6 +56,13 @@ public PropertiesFileConfiguration(params string[] lines)
public static ICustomConfiguration Instance { get; }
= new PropertiesFileConfiguration();
+ ///
+ public Version GetDockerApiVersion()
+ {
+ const string propertyName = "docker.api.version";
+ return GetDockerApiVersion(propertyName);
+ }
+
///
public string GetDockerConfig()
{
diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
index 1ed591185..810872503 100644
--- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
+++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/DockerTlsFixture.cs
@@ -9,7 +9,7 @@ public sealed class DockerTlsFixture : ProtectDockerDaemonSocket
{
public DockerTlsFixture()
: base(new ContainerBuilder()
- .WithCommand("--tlsverify=false"), "20.10.18")
+ .WithCommand("--tlsverify=false"), "29.0.0")
{
}
diff --git a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/OpenSsl3_1Fixture.cs b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/OpenSsl3_1Fixture.cs
index 0a4768b96..9b50c72f3 100644
--- a/tests/Testcontainers.Tests/Fixtures/Containers/Unix/OpenSsl3_1Fixture.cs
+++ b/tests/Testcontainers.Tests/Fixtures/Containers/Unix/OpenSsl3_1Fixture.cs
@@ -5,7 +5,7 @@ namespace DotNet.Testcontainers.Tests.Fixtures
[UsedImplicitly]
public sealed class OpenSsl3_1Fixture : DockerMTls
{
- public OpenSsl3_1Fixture() : base("24.0.5")
+ public OpenSsl3_1Fixture() : base("29.0.0")
{
}
}
diff --git a/tests/Testcontainers.Tests/Unit/Configurations/CustomConfigurationTest.cs b/tests/Testcontainers.Tests/Unit/Configurations/CustomConfigurationTest.cs
index 1d123dea5..652c10be1 100644
--- a/tests/Testcontainers.Tests/Unit/Configurations/CustomConfigurationTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Configurations/CustomConfigurationTest.cs
@@ -15,6 +15,7 @@ public sealed class EnvironmentConfigurationTest : IDisposable
static EnvironmentConfigurationTest()
{
+ EnvironmentVariables.Add("DOCKER_API_VERSION");
EnvironmentVariables.Add("DOCKER_CONFIG");
EnvironmentVariables.Add("DOCKER_HOST");
EnvironmentVariables.Add("DOCKER_CONTEXT");
@@ -34,6 +35,18 @@ static EnvironmentConfigurationTest()
EnvironmentVariables.Add("TESTCONTAINERS_NAMED_PIPE_CONNECTION_TIMEOUT");
}
+ [Theory]
+ [InlineData("", "", null)]
+ [InlineData("DOCKER_API_VERSION", "", null)]
+ [InlineData("DOCKER_API_VERSION", "version", null)]
+ [InlineData("DOCKER_API_VERSION", "1.52", "1.52")]
+ public void GetDockerApiVersionCustomConfiguration(string propertyName, string propertyValue, string expected)
+ {
+ SetEnvironmentVariable(propertyName, propertyValue);
+ ICustomConfiguration customConfiguration = new EnvironmentConfiguration();
+ Assert.Equal(expected, customConfiguration.GetDockerApiVersion()?.ToString());
+ }
+
[Theory]
[InlineData("", "", null)]
[InlineData("DOCKER_CONFIG", "", null)]
@@ -259,6 +272,17 @@ private static void SetEnvironmentVariable(string propertyName, string propertyV
public sealed class PropertiesFileConfigurationTest
{
+ [Theory]
+ [InlineData("", null)]
+ [InlineData("docker.api.version=", null)]
+ [InlineData("docker.api.version=version", null)]
+ [InlineData("docker.api.version=1.52", "1.52")]
+ public void GetDockerApiVersionCustomConfiguration(string configuration, string expected)
+ {
+ ICustomConfiguration customConfiguration = new PropertiesFileConfiguration(new[] { configuration });
+ Assert.Equal(expected, customConfiguration.GetDockerApiVersion()?.ToString());
+ }
+
[Theory]
[InlineData("", null)]
[InlineData("docker.config=", null)]
diff --git a/tests/Testcontainers.Tests/Unit/Containers/Unix/ProtectDockerDaemonSocketTest.cs b/tests/Testcontainers.Tests/Unit/Containers/Unix/ProtectDockerDaemonSocketTest.cs
index e73f7367a..19dee143f 100644
--- a/tests/Testcontainers.Tests/Unit/Containers/Unix/ProtectDockerDaemonSocketTest.cs
+++ b/tests/Testcontainers.Tests/Unit/Containers/Unix/ProtectDockerDaemonSocketTest.cs
@@ -3,6 +3,7 @@ namespace DotNet.Testcontainers.Tests.Unit
using System;
using System.Linq;
using System.Threading.Tasks;
+ using Docker.DotNet;
using DotNet.Testcontainers.Builders;
using DotNet.Testcontainers.Clients;
using DotNet.Testcontainers.Configurations;
@@ -20,7 +21,7 @@ private static IDockerEndpointAuthenticationConfiguration GetAuthConfig(ProtectD
return new IDockerEndpointAuthenticationProvider[] { new MTlsEndpointAuthenticationProvider(customConfiguration), new TlsEndpointAuthenticationProvider(customConfiguration) }.First(authProvider => authProvider.IsApplicable()).GetAuthConfig();
}
- public sealed class MTlsOpenSsl1_1_1 : IClassFixture
+ public sealed class MTlsOpenSsl1_1_1 : IClassFixture, IDockerEndpointAuthenticationConfiguration
{
private readonly ProtectDockerDaemonSocket _fixture;
@@ -32,11 +33,25 @@ public MTlsOpenSsl1_1_1(OpenSsl1_1_1Fixture dockerMTlsFixture)
_authConfig = GetAuthConfig(dockerMTlsFixture);
}
+ // The outdated image isn't compatible with the default Docker Engine API version.
+ // For this test, we're overriding the version.
+ public Version Version
+ => null;
+
+ public Uri Endpoint
+ => _authConfig.Endpoint;
+
+ public Credentials Credentials
+ => _authConfig.Credentials;
+
+ public DockerClientConfiguration GetDockerClientConfiguration(Guid sessionId = default)
+ => _authConfig.GetDockerClientConfiguration(sessionId);
+
[Fact]
public async Task GetVersionReturnsVersion()
{
// Given
- var client = new TestcontainersClient(Guid.Empty, _authConfig, NullLogger.Instance);
+ var client = new TestcontainersClient(Guid.Empty, this, NullLogger.Instance);
// When
var version = await client.System.GetVersionAsync(TestContext.Current.CancellationToken)