Global configuration and customization of Testcontainers behavior. The TestcontainersConfiguration singleton provides centralized access to configuration settings from environment variables, properties files, and defaults.
Testcontainers configuration can be provided through multiple sources with the following precedence (highest to lowest):
TESTCONTAINERS_)~/.testcontainers.properties)testcontainers.properties on classpath)import org.testcontainers.utility.TestcontainersConfiguration;
/**
* Singleton class for accessing Testcontainers configuration.
* Provides configuration from environment variables, properties files, and defaults.
* Uses Lombok @Data for equals/hashCode/toString generation.
*/
@Data
public class TestcontainersConfiguration {
/**
* Get the singleton TestcontainersConfiguration instance.
* Instance is lazily initialized on first access.
*
* @return the configuration singleton
*/
public static TestcontainersConfiguration getInstance();
/**
* Get a configuration value from environment variable or properties file.
* Searches in order: environment variable, user properties, classpath properties.
* Environment variable names are converted: property.name -> TESTCONTAINERS_PROPERTY_NAME
* Exception: property names starting with "docker." do not get TESTCONTAINERS_ prefix.
*
* @param propertyName dot-separated property name (e.g., "ryuk.container.timeout")
* @param defaultValue value to return if property not found
* @return the property value, or defaultValue if not found
*/
public String getEnvVarOrProperty(@NotNull String propertyName, @Nullable String defaultValue);
/**
* Get a configuration value from environment variable or user properties file only.
* Does not search classpath properties.
*
* @param propertyName dot-separated property name
* @param defaultValue value to return if property not found
* @return the property value, or defaultValue if not found
*/
public String getEnvVarOrUserProperty(@NotNull String propertyName, @Nullable String defaultValue);
/**
* Get a configuration value from user properties file only (~/.testcontainers.properties).
* Does not search environment variables or classpath properties.
*
* @param propertyName dot-separated property name
* @param defaultValue value to return if property not found
* @return the property value, or defaultValue if not found
*/
public String getUserProperty(@NotNull String propertyName, @Nullable String defaultValue);
/**
* Update a property in the user configuration file (~/.testcontainers.properties).
* Creates the file if it doesn't exist. Thread-safe.
*
* @param prop property name to update
* @param value new property value
* @return true if update succeeded, false otherwise
*/
public boolean updateUserConfig(@NonNull String prop, @NonNull String value);
/**
* Check if Testcontainers pre-flight checks are disabled.
* Controlled by: checks.disable property or TESTCONTAINERS_CHECKS_DISABLE env var.
*
* @return true if checks are disabled, false otherwise (default: false)
*/
public boolean isDisableChecks();
/**
* Check if container reuse is enabled in the environment.
* When enabled, containers marked with .withReuse(true) can persist between test runs.
* Controlled by: testcontainers.reuse.enable property.
* Marked @UnstableAPI - subject to change in future versions.
*
* @return true if reuse is enabled, false otherwise (default: false)
*/
@UnstableAPI
public boolean environmentSupportsReuse();
/**
* Get the fully qualified class name of the Docker client strategy to use.
* Determines how Testcontainers connects to the Docker daemon.
* Special handling: looks for TESTCONTAINERS_DOCKER_CLIENT_STRATEGY env var,
* then docker.client.strategy property.
*
* @return strategy class name, or null to use auto-detection
*/
public String getDockerClientStrategyClassName();
/**
* Get the transport type for Docker client communication.
* Controlled by: transport.type property or TESTCONTAINERS_TRANSPORT_TYPE env var.
*
* @return transport type (default: "httpclient5")
*/
public String getTransportType();
/**
* Get the fully qualified class name of the image substitutor to use.
* Image substitutors can replace image names globally (e.g., for using a private registry).
* Controlled by: image.substitutor property or TESTCONTAINERS_IMAGE_SUBSTITUTOR env var.
*
* @return substitutor class name, or null for no substitution
*/
public String getImageSubstitutorClassName();
/**
* Get the image pull policy class name or configuration.
* Controls when images are pulled from the registry.
* Controlled by: pull.policy property or TESTCONTAINERS_PULL_POLICY env var.
*
* @return pull policy class name or configuration, or null for default policy
*/
public String getImagePullPolicy();
/**
* Get the timeout for pausing during image pull operations (in seconds).
* Controlled by: pull.pause.timeout property.
*
* @return pause timeout in seconds (default: 30)
*/
public Integer getImagePullPauseTimeout();
/**
* Get the overall timeout for image pull operations (in seconds).
* Controlled by: pull.timeout property.
*
* @return pull timeout in seconds (default: 120)
*/
public Integer getImagePullTimeout();
/**
* Get the timeout for Docker client ping operations (in seconds).
* Used during Docker client initialization to verify connectivity.
* Controlled by: client.ping.timeout property.
*
* @return ping timeout in seconds (default: 10)
*/
public Integer getClientPingTimeout();
/**
* Check if Ryuk container should run in privileged mode.
* Ryuk handles resource cleanup at JVM shutdown.
* Controlled by: ryuk.container.privileged property.
*
* @return true if privileged mode enabled (default: true)
*/
public boolean isRyukPrivileged();
/**
* Get the timeout for Ryuk container startup (in seconds).
* Controlled by: ryuk.container.timeout property.
*
* @return ryuk timeout in seconds (default: 30)
*/
public Integer getRyukTimeout();
/**
* Get all properties from user and classpath sources.
* Does NOT include environment variables.
*
* @return merged properties from user and classpath files
* @deprecated Use specific getEnvVarOrProperty/getEnvVarOrUserProperty/getUserProperty methods instead
*/
@Deprecated
public Properties getProperties();
/**
* Update global configuration (alias for updateUserConfig).
*
* @param prop property name
* @param value property value
* @return true if update succeeded
* @deprecated Use updateUserConfig instead
*/
@Deprecated
public boolean updateGlobalConfig(@NonNull String prop, @NonNull String value);
}The user configuration file is located at ~/.testcontainers.properties and uses standard Java properties format:
# Docker connection
docker.client.strategy=org.testcontainers.dockerclient.UnixSocketClientProviderStrategy
transport.type=httpclient5
# Image management
image.substitutor=org.testcontainers.utility.FooImageNameSubstitutor
pull.policy=org.testcontainers.images.PullPolicy$AlwaysPull
# Container reuse (development mode)
testcontainers.reuse.enable=true
# Ryuk (resource cleanup) configuration
ryuk.container.privileged=false
ryuk.container.timeout=60
# Disable pre-flight checks (not recommended for production)
checks.disable=false
# Timeouts
pull.pause.timeout=30
pull.timeout=120
client.ping.timeout=10
# Custom container images (override defaults)
ryuk.container.image=testcontainers/ryuk:0.5.1
tinyimage.container.image=alpine:3.17You can also provide a testcontainers.properties file on your classpath (e.g., in src/test/resources/). This is useful for project-specific defaults:
# Project-wide test settings
testcontainers.reuse.enable=true
pull.policy=defaultAll properties can be set via environment variables. The conversion rules are:
.) with underscores (_)TESTCONTAINERS_ (except for docker.* properties)Examples:
| Property Name | Environment Variable |
|---|---|
ryuk.container.timeout | TESTCONTAINERS_RYUK_CONTAINER_TIMEOUT |
testcontainers.reuse.enable | TESTCONTAINERS_TESTCONTAINERS_REUSE_ENABLE |
docker.client.strategy | TESTCONTAINERS_DOCKER_CLIENT_STRATEGY or DOCKER_CLIENT_STRATEGY |
image.substitutor | TESTCONTAINERS_IMAGE_SUBSTITUTOR |
checks.disable | TESTCONTAINERS_CHECKS_DISABLE |
Setting environment variables:
# Bash/Linux/macOS
export TESTCONTAINERS_REUSE_ENABLE=true
export TESTCONTAINERS_RYUK_CONTAINER_TIMEOUT=60
# Windows PowerShell
$env:TESTCONTAINERS_REUSE_ENABLE="true"
$env:TESTCONTAINERS_RYUK_CONTAINER_TIMEOUT="60"
# Docker Compose
environment:
- TESTCONTAINERS_REUSE_ENABLE=true
- TESTCONTAINERS_RYUK_CONTAINER_TIMEOUT=60Container reuse allows containers marked with .withReuse(true) to persist between test runs, dramatically speeding up development:
# ~/.testcontainers.properties
testcontainers.reuse.enable=trueimport org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.DockerImageName;
GenericContainer<?> redis = new GenericContainer<>(DockerImageName.parse("redis:7.0"))
.withExposedPorts(6379)
.withReuse(true); // Container will persist between test runs
redis.start();
// Container stays running after test completesImportant: Container reuse is disabled by default for safety. Only enable in development environments.
Specify how Testcontainers should connect to Docker:
# Use Unix socket (Linux/macOS default)
docker.client.strategy=org.testcontainers.dockerclient.UnixSocketClientProviderStrategy
# Use Docker Desktop (Windows/macOS)
docker.client.strategy=org.testcontainers.dockerclient.DockerMachineClientProviderStrategy
# Use environment variables (DOCKER_HOST, etc.)
docker.client.strategy=org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategyOr via environment variable:
export TESTCONTAINERS_DOCKER_CLIENT_STRATEGY=org.testcontainers.dockerclient.UnixSocketClientProviderStrategyRedirect all image pulls to a private registry:
# Configure image substitutor
image.substitutor=org.testcontainers.utility.PrefixingImageNameSubstitutor// Implement custom substitutor
public class PrivateRegistrySubstitutor extends ImageNameSubstitutor {
@Override
public DockerImageName apply(DockerImageName original) {
return DockerImageName.parse("my-registry.com/" + original.asCanonicalNameString())
.asCompatibleSubstituteFor(original);
}
}Disable Docker environment validation checks (not recommended for CI/production):
checks.disable=trueOr programmatically:
import org.testcontainers.utility.TestcontainersConfiguration;
// Check if disabled
boolean disabled = TestcontainersConfiguration.getInstance().isDisableChecks();Configure timeouts for Docker operations:
# Image pull timeout (seconds)
pull.timeout=300
# Pause between pull retries (seconds)
pull.pause.timeout=60
# Docker client ping timeout (seconds)
client.ping.timeout=30
# Ryuk startup timeout (seconds)
ryuk.container.timeout=60Ryuk is the resource cleanup container that runs at JVM shutdown. Configure its behavior:
# Run Ryuk without privileged mode (some environments don't allow it)
ryuk.container.privileged=false
# Increase Ryuk startup timeout
ryuk.container.timeout=60
# Use custom Ryuk image version
ryuk.container.image=testcontainers/ryuk:0.5.1Testcontainers uses several utility containers. You can override their images:
# Ryuk (resource cleanup)
ryuk.container.image=testcontainers/ryuk:0.5.1
# Tiny image (used for internal operations)
tinyimage.container.image=alpine:3.17
# Socat (port forwarding)
socat.container.image=alpine/socat:latest
# VNC recorder (for visual testing)
vncrecorder.container.image=testcontainers/vnc-recorder:1.3.0
# Docker Compose
compose.container.image=docker/compose:1.29.2
# SSHD (for tunneling)
sshd.container.image=testcontainers/sshd:1.1.0import org.testcontainers.utility.TestcontainersConfiguration;
TestcontainersConfiguration config = TestcontainersConfiguration.getInstance();
// Check if reuse is enabled
boolean reuseEnabled = config.environmentSupportsReuse();
if (reuseEnabled) {
System.out.println("Container reuse is enabled");
}
// Get Docker client strategy
String strategy = config.getDockerClientStrategyClassName();
System.out.println("Using Docker client strategy: " + strategy);
// Get custom property
String customValue = config.getEnvVarOrProperty("my.custom.property", "default-value");
System.out.println("Custom property: " + customValue);
// Get timeout values
int pullTimeout = config.getImagePullTimeout();
int ryukTimeout = config.getRyukTimeout();
System.out.println("Pull timeout: " + pullTimeout + "s, Ryuk timeout: " + ryukTimeout + "s");import org.testcontainers.utility.TestcontainersConfiguration;
TestcontainersConfiguration config = TestcontainersConfiguration.getInstance();
// Enable reuse programmatically (writes to ~/.testcontainers.properties)
boolean updated = config.updateUserConfig("testcontainers.reuse.enable", "true");
if (updated) {
System.out.println("Configuration updated successfully");
} else {
System.err.println("Failed to update configuration");
}
// Set custom timeout
config.updateUserConfig("ryuk.container.timeout", "120");
// Configure image substitutor
config.updateUserConfig("image.substitutor", "com.example.MyImageSubstitutor");Note: Configuration updates are written to ~/.testcontainers.properties and affect future test runs. The currently running JVM will not see the changes until it's restarted.
import org.testcontainers.utility.TestcontainersConfiguration;
// Given:
// - Environment variable: TESTCONTAINERS_RYUK_CONTAINER_TIMEOUT=100
// - ~/.testcontainers.properties: ryuk.container.timeout=60
// - Default value: 30
TestcontainersConfiguration config = TestcontainersConfiguration.getInstance();
// Returns 100 (environment variable takes precedence)
int timeout = config.getRyukTimeout();
// Explicitly check each source
String envOnly = config.getEnvVarOrUserProperty("ryuk.container.timeout", "default");
// Returns: 100 (from env var)
String userOnly = config.getUserProperty("ryuk.container.timeout", "default");
// Returns: 60 (from user properties, ignoring env var)name: Integration Tests
on: [push]
jobs:
test:
runs-on: ubuntu-latest
env:
# Configure Testcontainers for CI
TESTCONTAINERS_CHECKS_DISABLE: false
TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED: true
TESTCONTAINERS_PULL_TIMEOUT: 300
steps:
- uses: actions/checkout@v3
- name: Set up JDK 11
uses: actions/setup-java@v3
with:
java-version: '11'
- name: Run tests
run: mvn testtest:
image: maven:3.8-openjdk-11
services:
- docker:dind
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
TESTCONTAINERS_CHECKS_DISABLE: "false"
TESTCONTAINERS_RYUK_CONTAINER_TIMEOUT: "60"
script:
- mvn testpipeline {
agent any
environment {
TESTCONTAINERS_CHECKS_DISABLE = 'false'
TESTCONTAINERS_RYUK_CONTAINER_PRIVILEGED = 'true'
TESTCONTAINERS_PULL_TIMEOUT = '300'
}
stages {
stage('Test') {
steps {
sh 'mvn test'
}
}
}
}import org.testcontainers.utility.TestcontainersConfiguration;
import java.util.Properties;
TestcontainersConfiguration config = TestcontainersConfiguration.getInstance();
// Print all configuration
System.out.println("Docker client strategy: " + config.getDockerClientStrategyClassName());
System.out.println("Transport type: " + config.getTransportType());
System.out.println("Image substitutor: " + config.getImageSubstitutorClassName());
System.out.println("Pull policy: " + config.getImagePullPolicy());
System.out.println("Reuse enabled: " + config.environmentSupportsReuse());
System.out.println("Checks disabled: " + config.isDisableChecks());
System.out.println("Ryuk privileged: " + config.isRyukPrivileged());
System.out.println("Ryuk timeout: " + config.getRyukTimeout());
System.out.println("Pull timeout: " + config.getImagePullTimeout());~/.testcontainers.properties is in the correct location| Problem | Solution |
|---|---|
| Reuse not working | Verify testcontainers.reuse.enable=true in properties file |
| Wrong Docker host | Check DOCKER_HOST environment variable |
| Image pull timeouts | Increase pull.timeout property |
| Ryuk fails to start | Try ryuk.container.privileged=false or increase timeout |
| Configuration file not found | Check ~/.testcontainers.properties exists and is readable |
| Environment variable ignored | Verify correct naming (TESTCONTAINERS_ prefix) |
testcontainers.propertiestestcontainers.reuse.enable=false in CI/CDsrc/test/resources/testcontainers.properties to git~/.testcontainers.properties out of version control (contains local settings)# ~/.testcontainers.properties - Local development configuration
# ============================================
# Docker Connection
# ============================================
docker.client.strategy=org.testcontainers.dockerclient.UnixSocketClientProviderStrategy
transport.type=httpclient5
# ============================================
# Image Management
# ============================================
# Use private registry for all images
image.substitutor=com.example.PrivateRegistrySubstitutor
# Always pull latest images (useful for development)
pull.policy=org.testcontainers.images.PullPolicy$AlwaysPull
# Image pull timeouts
pull.timeout=300
pull.pause.timeout=60
# ============================================
# Container Reuse (Development Only)
# ============================================
testcontainers.reuse.enable=true
# ============================================
# Ryuk Configuration
# ============================================
ryuk.container.privileged=false
ryuk.container.timeout=60
ryuk.container.image=testcontainers/ryuk:0.5.1
# ============================================
# Utility Container Images
# ============================================
tinyimage.container.image=alpine:3.17
socat.container.image=alpine/socat:1.7.4.3
vncrecorder.container.image=testcontainers/vnc-recorder:1.3.0
# ============================================
# Timeouts
# ============================================
client.ping.timeout=30
# ============================================
# Pre-flight Checks
# ============================================
checks.disable=false
# ============================================
# Custom Project Settings
# ============================================
my.project.database.version=15
my.project.redis.version=7.0This comprehensive configuration documentation covers all aspects of the TestcontainersConfiguration API, providing users with complete control over Testcontainers behavior through properties files, environment variables, and programmatic access.