or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

configuration.mdcontainer-lifecycle.mddocker-client.mddocker-compose.mdimage-building.mdimage-management.mdimage-pull-policies.mdindex.mdjunit-jupiter-integration.mdlifecycle.mdmodules-overview.mdnetwork-configuration.mdoutput-handling.mdstartup-checks.mdutility-classes.mdwait-strategies.md
tile.json

modules-overview.mddocs/

Testcontainers Modules Overview

Testcontainers provides specialized container modules for popular databases, message queues, and other services. These modules extend GenericContainer or JdbcDatabaseContainer with service-specific configuration methods and connection helpers, simplifying integration testing against real service instances.

Overview

Why Use Modules?

  • Simpler configuration: Pre-configured ports, environment variables, and wait strategies
  • Type-safe connection access: Methods like getJdbcUrl(), getConnectionString()
  • Service-specific features: Database initialization, replica set configuration, etc.
  • Best practices built-in: Optimal wait strategies and startup checks

When to Use Modules vs GenericContainer:

  • Use modules: For supported databases, message queues, and services (easier, more features)
  • Use GenericContainer: For custom images or unsupported services (more flexible)

Package Information

Modules are distributed as separate Maven/Gradle dependencies:

Maven:

<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>postgresql</artifactId>  <!-- Module name -->
    <version>2.0.3</version>
    <scope>test</scope>
</dependency>

Gradle:

testImplementation 'org.testcontainers:postgresql:2.0.3'

Available Modules

Database Modules

ModuleArtifact IDContainer ClassConnection Method
PostgreSQLpostgresqlPostgreSQLContainergetJdbcUrl()
MySQLmysqlMySQLContainergetJdbcUrl()
MariaDBmariadbMariaDBContainergetJdbcUrl()
MongoDBmongodbMongoDBContainergetConnectionString()
Oracle XEoracle-xeOracleContainergetJdbcUrl()
Oracle Freeoracle-freeOracleFreeContainergetJdbcUrl()
MS SQL ServermssqlserverMSSQLServerContainergetJdbcUrl()
DB2db2Db2ContainergetJdbcUrl()
CassandracassandraCassandraContainergetContactPoint()
Neo4jneo4jNeo4jContainergetBoltUrl()
CockroachDBcockroachdbCockroachContainergetJdbcUrl()
CouchbasecouchbaseCouchbaseContainergetConnectionString()
ClickHouseclickhouseClickHouseContainergetJdbcUrl()
InfluxDBinfluxdbInfluxDBContainergetUrl()
QuestDBquestdbQuestDBContainergetHttpUrl()
TiDBtidbTiDBContainergetJdbcUrl()
YugabyteDByugabytedbYugabyteDBContainergetJdbcUrl()
CrateDBcratedbCrateDBContainergetJdbcUrl()
OrientDBorientdbOrientDBContainergetDbUrl()
DatabenddatabendDatabendContainergetJdbcUrl()
ScyllaDBscylladbScyllaDBContainergetContactPoint()
OceanBaseoceanbaseOceanBaseContainergetJdbcUrl()

Message Queue Modules

ModuleArtifact IDContainer ClassConnection Method
KafkakafkaKafkaContainergetBootstrapServers()
RabbitMQrabbitmqRabbitMQContainergetAmqpUrl() / getHttpUrl()
PulsarpulsarPulsarContainergetPulsarBrokerUrl()
RedpandaredpandaRedpandaContainergetBootstrapServers()
ActiveMQactivemqActiveMQContainergetBrokerUrl()
HiveMQhivemqHiveMQContainergetMqttPort()
SolacesolaceSolaceContainergetOrigin()

Search & Analytics Modules

ModuleArtifact IDContainer ClassConnection Method
ElasticsearchelasticsearchElasticsearchContainergetHttpHostAddress()
SolrsolrSolrContainergetSolrUrl()
MilvusmilvusMilvusContainergetEndpoint()
QdrantqdrantQdrantContainergetGrpcHostAddress()
WeaviateweaviateWeaviateContainergetHttpHostAddress()
PineconepineconePineconeContainergetEndpoint()
ChromaDBchromadbChromaDBContainergetEndpoint()
TypesensetypesenseTypesenseContainergetHost()

Cloud & Infrastructure Modules

ModuleArtifact IDContainer ClassUse Case
LocalStacklocalstackLocalStackContainerAWS service emulation
AzureazureAzuriteContainerAzure Blob/Queue/Table storage
GCloudgcloudFirestoreEmulatorContainer, PubSubEmulatorContainer, BigtableEmulatorContainerGoogle Cloud emulation
VaultvaultVaultContainerHashiCorp Vault secrets management
ConsulconsulConsulContainerService discovery
MinIOminioMinIOContainerS3-compatible object storage
K3sk3sK3sContainerLightweight Kubernetes
K6k6K6ContainerLoad testing

Testing & Development Modules

ModuleArtifact IDContainer ClassUse Case
SeleniumseleniumBrowserWebDriverContainerBrowser automation
MockServermockserverMockServerContainerHTTP API mocking
NginxnginxNginxContainerWeb server / reverse proxy
ToxiproxytoxiproxyToxiproxyContainerNetwork failure simulation
OpenFGAopenfgaOpenFGAContainerAuthorization service
GrafanagrafanaGrafanaContainerMetrics visualization
LDAPldapLdapContainerLDAP server
OllamaollamaOllamaContainerLLM inference
PrestoprestoPrestoContainerDistributed SQL query
TrinotrinoTrinoContainerDistributed SQL query
TimeplustimeplusTimeplusContainerStream processing

Database Modules

PostgreSQLContainer

PostgreSQL database container with JDBC support.

package org.testcontainers.postgresql;

/**
 * PostgreSQL database container.
 * Extends JdbcDatabaseContainer with PostgreSQL-specific configuration.
 *
 * Default port: 5432
 * Default database: test
 * Default username: test
 * Default password: test
 * JDBC driver: org.postgresql.Driver
 */
public class PostgreSQLContainer<SELF extends PostgreSQLContainer<SELF>>
    extends JdbcDatabaseContainer<SELF> {

    /**
     * Create PostgreSQL container with default postgres:latest image.
     * @deprecated Use constructor with DockerImageName
     */
    @Deprecated
    public PostgreSQLContainer();

    /**
     * Create PostgreSQL container with specific image.
     *
     * @param dockerImageName PostgreSQL Docker image
     */
    public PostgreSQLContainer(DockerImageName dockerImageName);

    /**
     * Create PostgreSQL container with image name string.
     *
     * @param dockerImageName image name (e.g., "postgres:15")
     */
    public PostgreSQLContainer(String dockerImageName);

    /**
     * Get JDBC URL for connecting to the database.
     * Format: jdbc:postgresql://host:port/database
     *
     * @return JDBC URL string
     */
    @Override
    public String getJdbcUrl();

    /**
     * Get JDBC driver class name.
     *
     * @return "org.postgresql.Driver"
     */
    @Override
    public String getDriverClassName();

    /**
     * Get the database name.
     *
     * @return database name (default: "test")
     */
    @Override
    public String getDatabaseName();

    /**
     * Get the username.
     *
     * @return username (default: "test")
     */
    @Override
    public String getUsername();

    /**
     * Get the password.
     *
     * @return password (default: "test")
     */
    @Override
    public String getPassword();

    /**
     * Get the test query SQL used for connection validation.
     *
     * @return test query (default: "SELECT 1")
     */
    @Override
    protected String getTestQueryString();

    /**
     * Set database name.
     *
     * @param databaseName database name
     * @return this container
     */
    public SELF withDatabaseName(String databaseName);

    /**
     * Set username.
     *
     * @param username username
     * @return this container
     */
    public SELF withUsername(String username);

    /**
     * Set password.
     *
     * @param password password
     * @return this container
     */
    public SELF withPassword(String password);

    /**
     * Set initialization script to run on startup.
     * Script is executed after the database is ready.
     *
     * @param initScriptPath classpath resource path to SQL script
     * @return this container
     */
    public SELF withInitScript(String initScriptPath);
}

Usage Example:

import org.testcontainers.postgresql.PostgreSQLContainer;
import org.testcontainers.utility.DockerImageName;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

// Basic usage
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15");
postgres.start();

// Get connection details
String jdbcUrl = postgres.getJdbcUrl();
String username = postgres.getUsername();
String password = postgres.getPassword();

// Connect using JDBC
try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
    ResultSet rs = conn.createStatement().executeQuery("SELECT version()");
    rs.next();
    System.out.println("PostgreSQL version: " + rs.getString(1));
}

// Custom configuration
PostgreSQLContainer<?> customPostgres = new PostgreSQLContainer<>(
        DockerImageName.parse("postgres:15-alpine"))
    .withDatabaseName("mydb")
    .withUsername("myuser")
    .withPassword("mypass")
    .withInitScript("schema.sql");  // Run initialization script

customPostgres.start();

MySQLContainer

MySQL database container with JDBC support.

package org.testcontainers.mysql;

/**
 * MySQL database container.
 * Extends JdbcDatabaseContainer with MySQL-specific configuration.
 *
 * Default port: 3306
 * Default database: test
 * Default username: test
 * Default password: test
 * JDBC driver: com.mysql.cj.jdbc.Driver (or com.mysql.jdbc.Driver for older versions)
 *
 * Automatically adds useSSL=false and allowPublicKeyRetrieval=true to JDBC URL.
 */
public class MySQLContainer<SELF extends MySQLContainer<SELF>>
    extends JdbcDatabaseContainer<SELF> {

    /**
     * Create MySQL container with specific image.
     *
     * @param dockerImageName MySQL Docker image
     */
    public MySQLContainer(DockerImageName dockerImageName);

    /**
     * Create MySQL container with image name string.
     *
     * @param dockerImageName image name (e.g., "mysql:8.0")
     */
    public MySQLContainer(String dockerImageName);

    /**
     * Get JDBC URL for connecting to the database.
     * Format: jdbc:mysql://host:port/database?useSSL=false&allowPublicKeyRetrieval=true
     *
     * @return JDBC URL string
     */
    @Override
    public String getJdbcUrl();

    /**
     * Get JDBC driver class name.
     *
     * @return "com.mysql.cj.jdbc.Driver" or fallback for older versions
     */
    @Override
    public String getDriverClassName();

    /**
     * Get the database name.
     *
     * @return database name (default: "test")
     */
    @Override
    public String getDatabaseName();

    /**
     * Get the username.
     *
     * @return username (default: "test")
     */
    @Override
    public String getUsername();

    /**
     * Get the password.
     *
     * @return password (default: "test")
     */
    @Override
    public String getPassword();

    /**
     * Get the test query SQL.
     *
     * @return test query (default: "SELECT 1")
     */
    @Override
    protected String getTestQueryString();

    /**
     * Set database name.
     *
     * @param databaseName database name
     * @return this container
     */
    public SELF withDatabaseName(String databaseName);

    /**
     * Set username.
     *
     * @param username username
     * @return this container
     */
    public SELF withUsername(String username);

    /**
     * Set password.
     *
     * @param password password
     * @return this container
     */
    public SELF withPassword(String password);

    /**
     * Set MySQL configuration file override.
     * Mounts a custom my.cnf file to override MySQL configuration.
     *
     * @param configurationPath classpath path to my.cnf file
     * @return this container
     */
    public SELF withConfigurationOverride(String configurationPath);

    /**
     * Set initialization script.
     *
     * @param initScriptPath classpath resource path to SQL script
     * @return this container
     */
    public SELF withInitScript(String initScriptPath);
}

Usage Example:

import org.testcontainers.mysql.MySQLContainer;

// Basic usage
MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0");
mysql.start();

String jdbcUrl = mysql.getJdbcUrl();
// jdbc:mysql://localhost:32768/test?useSSL=false&allowPublicKeyRetrieval=true

// Custom configuration with my.cnf override
MySQLContainer<?> customMySQL = new MySQLContainer<>("mysql:8.0")
    .withDatabaseName("appdb")
    .withUsername("app")
    .withPassword("secret")
    .withConfigurationOverride("mysql-config")  // Mounts classpath:mysql-config/my.cnf
    .withInitScript("init.sql");

customMySQL.start();

// Connect
try (Connection conn = DriverManager.getConnection(
        customMySQL.getJdbcUrl(),
        customMySQL.getUsername(),
        customMySQL.getPassword())) {
    // Use connection
}

MongoDBContainer

MongoDB NoSQL database container (does NOT extend JdbcDatabaseContainer).

package org.testcontainers.mongodb;

/**
 * MongoDB database container.
 * Extends GenericContainer (not JdbcDatabaseContainer).
 *
 * Default port: 27017
 * No default authentication
 * Uses MongoDB connection strings (not JDBC URLs)
 *
 * Supports:
 * - Standalone mode (default)
 * - Replica set mode (required for transactions)
 * - Sharding mode
 */
public class MongoDBContainer extends GenericContainer<MongoDBContainer> {

    /**
     * Create MongoDB container with specific image.
     *
     * @param dockerImageName MongoDB Docker image
     */
    public MongoDBContainer(DockerImageName dockerImageName);

    /**
     * Create MongoDB container with image name string.
     *
     * @param dockerImageName image name (e.g., "mongo:7.0")
     */
    public MongoDBContainer(String dockerImageName);

    /**
     * Get MongoDB connection string.
     * Format: mongodb://host:port
     *
     * @return MongoDB connection string
     */
    public String getConnectionString();

    /**
     * Get replica set connection URL.
     * Only valid if withReplicaSet() was called.
     * Format: mongodb://host:port/?replicaSet=rs0
     *
     * @return replica set URL
     */
    public String getReplicaSetUrl();

    /**
     * Get replica set connection URL for a specific database.
     * Format: mongodb://host:port/database?replicaSet=rs0
     *
     * @param database database name
     * @return replica set URL with database
     */
    public String getReplicaSetUrl(String database);

    /**
     * Enable replica set mode.
     * Required for MongoDB transactions.
     * Configures single-node replica set named "rs0".
     *
     * @return this container
     */
    public MongoDBContainer withReplicaSet();

    /**
     * Enable sharding mode.
     * Configures MongoDB with sharding support.
     *
     * @return this container
     */
    public MongoDBContainer withSharding();
}

Usage Example:

import org.testcontainers.mongodb.MongoDBContainer;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.client.MongoDatabase;

// Basic standalone MongoDB
MongoDBContainer mongodb = new MongoDBContainer("mongo:7.0");
mongodb.start();

String connectionString = mongodb.getConnectionString();
// mongodb://localhost:32769

// Connect using MongoDB driver
try (MongoClient mongoClient = MongoClients.create(connectionString)) {
    MongoDatabase database = mongoClient.getDatabase("testdb");
    // Use database
}

// Replica set mode (required for transactions)
MongoDBContainer replicaSet = new MongoDBContainer("mongo:7.0")
    .withReplicaSet();

replicaSet.start();

String replicaSetUrl = replicaSet.getReplicaSetUrl("mydb");
// mongodb://localhost:32770/mydb?replicaSet=rs0

try (MongoClient client = MongoClients.create(replicaSetUrl)) {
    // Can now use transactions
    ClientSession session = client.startSession();
    session.startTransaction();
    try {
        // Transactional operations
        session.commitTransaction();
    } catch (Exception e) {
        session.abortTransaction();
    }
}

Message Queue Modules

KafkaContainer

Apache Kafka message broker container.

package org.testcontainers.kafka;

/**
 * Kafka message broker container.
 * Runs Kafka with embedded ZooKeeper or KRaft mode.
 *
 * Default port: 9093 (internal), mapped dynamically
 * Supports both ZooKeeper and KRaft (ZooKeeper-less) modes
 */
public class KafkaContainer extends GenericContainer<KafkaContainer> {

    /**
     * Create Kafka container with specific image.
     *
     * @param dockerImageName Kafka Docker image (confluentinc/cp-kafka)
     */
    public KafkaContainer(DockerImageName dockerImageName);

    /**
     * Get Kafka bootstrap servers connection string.
     * Format: PLAINTEXT://host:port
     *
     * @return bootstrap servers string
     */
    public String getBootstrapServers();

    /**
     * Enable KRaft mode (ZooKeeper-less).
     * Available in Kafka 3.3+.
     *
     * @return this container
     */
    public KafkaContainer withKraft();

    /**
     * Create topics on startup.
     * Topics are automatically created after Kafka is ready.
     *
     * @param numPartitions number of partitions per topic
     * @param replicationFactor replication factor (use 1 for single broker)
     * @param topics topic names to create
     * @return this container
     */
    public KafkaContainer withCreateTopics(int numPartitions, short replicationFactor, String... topics);
}

Usage Example:

import org.testcontainers.kafka.KafkaContainer;
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Properties;

// Basic Kafka
KafkaContainer kafka = new KafkaContainer(
    DockerImageName.parse("confluentinc/cp-kafka:7.5.0"));
kafka.start();

String bootstrapServers = kafka.getBootstrapServers();
// PLAINTEXT://localhost:32771

// Producer configuration
Properties producerProps = new Properties();
producerProps.put("bootstrap.servers", bootstrapServers);
producerProps.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
producerProps.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

KafkaProducer<String, String> producer = new KafkaProducer<>(producerProps);
producer.send(new ProducerRecord<>("test-topic", "key", "value"));

// With pre-created topics
KafkaContainer kafkaWithTopics = new KafkaContainer(
        DockerImageName.parse("confluentinc/cp-kafka:7.5.0"))
    .withCreateTopics(3, (short) 1, "events", "commands", "queries");

kafkaWithTopics.start();

Common Module Patterns

JDBC Database Pattern

All JDBC database modules (PostgreSQLContainer, MySQLContainer, etc.) share this pattern:

// Common JDBC database methods
JdbcDatabaseContainer<?> db = new PostgreSQLContainer<>("postgres:15");
db.start();

// Connection details
String jdbcUrl = db.getJdbcUrl();          // JDBC URL
String username = db.getUsername();         // Username (default: "test")
String password = db.getPassword();         // Password (default: "test")
String databaseName = db.getDatabaseName(); // Database name (default: "test")
String driverClassName = db.getDriverClassName(); // JDBC driver class

// JDBC connection
try (Connection conn = DriverManager.getConnection(jdbcUrl, username, password)) {
    // Use connection
}

// Common configuration
db.withDatabaseName("mydb")
  .withUsername("user")
  .withPassword("pass")
  .withInitScript("init.sql");  // Run SQL script on startup

Non-JDBC Database Pattern

NoSQL databases use service-specific connection methods:

// MongoDB
MongoDBContainer mongo = new MongoDBContainer("mongo:7.0");
mongo.start();
String connectionString = mongo.getConnectionString();
MongoClient client = MongoClients.create(connectionString);

// Cassandra
CassandraContainer cassandra = new CassandraContainer("cassandra:4.1");
cassandra.start();
InetSocketAddress contactPoint = cassandra.getContactPoint();
CqlSession session = CqlSession.builder()
    .addContactPoint(contactPoint)
    .withLocalDatacenter(cassandra.getLocalDatacenter())
    .build();

When to Use Modules vs GenericContainer

Use Specialized Modules When:

✅ Module exists for your service ✅ You need JDBC URL / connection string helpers ✅ You want service-specific configuration (replica sets, sharding, etc.) ✅ You need initialization scripts or pre-configuration

Example:

// ✅ Good - use PostgreSQL module
PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
    .withInitScript("schema.sql");

String jdbcUrl = postgres.getJdbcUrl();  // Easy!

Use GenericContainer When:

✅ No specialized module exists for your service ✅ You're using a custom or modified image ✅ You need maximum flexibility ✅ Service doesn't need special configuration

Example:

// ✅ Good - Redis has no specialized module
GenericContainer<?> redis = new GenericContainer<>("redis:7.0")
    .withExposedPorts(6379);

redis.start();

// Manual connection details
String host = redis.getHost();
int port = redis.getMappedPort(6379);

Module Dependencies and JDBC Drivers

Testcontainers modules do NOT include JDBC drivers. You must add them separately:

PostgreSQL:

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.6.0</version>
    <scope>test</scope>
</dependency>

MySQL:

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.1.0</version>
    <scope>test</scope>
</dependency>

MongoDB:

<dependency>
    <groupId>org.mongodb</groupId>
    <artifactId>mongodb-driver-sync</artifactId>
    <version>4.11.0</version>
    <scope>test</scope>
</dependency>

Complete Example: Multi-Database Test

import org.testcontainers.postgresql.PostgreSQLContainer;
import org.testcontainers.mysql.MySQLContainer;
import org.testcontainers.mongodb.MongoDBContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
import org.junit.jupiter.api.Test;

import java.sql.Connection;
import java.sql.DriverManager;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;

@Testcontainers
class MultiDatabaseTest {

    @Container
    private static PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>("postgres:15")
        .withDatabaseName("testdb")
        .withUsername("user")
        .withPassword("pass");

    @Container
    private static MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
        .withDatabaseName("testdb");

    @Container
    private static MongoDBContainer mongodb = new MongoDBContainer("mongo:7.0");

    @Test
    void testPostgreSQL() throws Exception {
        try (Connection conn = DriverManager.getConnection(
                postgres.getJdbcUrl(),
                postgres.getUsername(),
                postgres.getPassword())) {

            conn.createStatement().execute("CREATE TABLE users (id SERIAL PRIMARY KEY, name VARCHAR(255))");
            conn.createStatement().execute("INSERT INTO users (name) VALUES ('Alice')");

            var rs = conn.createStatement().executeQuery("SELECT COUNT(*) FROM users");
            rs.next();
            assertEquals(1, rs.getInt(1));
        }
    }

    @Test
    void testMySQL() throws Exception {
        try (Connection conn = DriverManager.getConnection(
                mysql.getJdbcUrl(),
                mysql.getUsername(),
                mysql.getPassword())) {

            conn.createStatement().execute("CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(255))");
            conn.createStatement().execute("INSERT INTO products VALUES (1, 'Widget')");

            var rs = conn.createStatement().executeQuery("SELECT * FROM products WHERE id = 1");
            rs.next();
            assertEquals("Widget", rs.getString("name"));
        }
    }

    @Test
    void testMongoDB() {
        try (MongoClient client = MongoClients.create(mongodb.getConnectionString())) {
            var database = client.getDatabase("testdb");
            var collection = database.getCollection("items");

            collection.insertOne(new Document("name", "Item1"));

            assertEquals(1, collection.countDocuments());
        }
    }
}

This modules overview provides coding agents with practical guidance for choosing and using Testcontainers specialized modules, with complete API documentation for the most common database and message queue containers.