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.
Why Use Modules?
getJdbcUrl(), getConnectionString()When to Use Modules vs GenericContainer:
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'| Module | Artifact ID | Container Class | Connection Method |
|---|---|---|---|
| PostgreSQL | postgresql | PostgreSQLContainer | getJdbcUrl() |
| MySQL | mysql | MySQLContainer | getJdbcUrl() |
| MariaDB | mariadb | MariaDBContainer | getJdbcUrl() |
| MongoDB | mongodb | MongoDBContainer | getConnectionString() |
| Oracle XE | oracle-xe | OracleContainer | getJdbcUrl() |
| Oracle Free | oracle-free | OracleFreeContainer | getJdbcUrl() |
| MS SQL Server | mssqlserver | MSSQLServerContainer | getJdbcUrl() |
| DB2 | db2 | Db2Container | getJdbcUrl() |
| Cassandra | cassandra | CassandraContainer | getContactPoint() |
| Neo4j | neo4j | Neo4jContainer | getBoltUrl() |
| CockroachDB | cockroachdb | CockroachContainer | getJdbcUrl() |
| Couchbase | couchbase | CouchbaseContainer | getConnectionString() |
| ClickHouse | clickhouse | ClickHouseContainer | getJdbcUrl() |
| InfluxDB | influxdb | InfluxDBContainer | getUrl() |
| QuestDB | questdb | QuestDBContainer | getHttpUrl() |
| TiDB | tidb | TiDBContainer | getJdbcUrl() |
| YugabyteDB | yugabytedb | YugabyteDBContainer | getJdbcUrl() |
| CrateDB | cratedb | CrateDBContainer | getJdbcUrl() |
| OrientDB | orientdb | OrientDBContainer | getDbUrl() |
| Databend | databend | DatabendContainer | getJdbcUrl() |
| ScyllaDB | scylladb | ScyllaDBContainer | getContactPoint() |
| OceanBase | oceanbase | OceanBaseContainer | getJdbcUrl() |
| Module | Artifact ID | Container Class | Connection Method |
|---|---|---|---|
| Kafka | kafka | KafkaContainer | getBootstrapServers() |
| RabbitMQ | rabbitmq | RabbitMQContainer | getAmqpUrl() / getHttpUrl() |
| Pulsar | pulsar | PulsarContainer | getPulsarBrokerUrl() |
| Redpanda | redpanda | RedpandaContainer | getBootstrapServers() |
| ActiveMQ | activemq | ActiveMQContainer | getBrokerUrl() |
| HiveMQ | hivemq | HiveMQContainer | getMqttPort() |
| Solace | solace | SolaceContainer | getOrigin() |
| Module | Artifact ID | Container Class | Connection Method |
|---|---|---|---|
| Elasticsearch | elasticsearch | ElasticsearchContainer | getHttpHostAddress() |
| Solr | solr | SolrContainer | getSolrUrl() |
| Milvus | milvus | MilvusContainer | getEndpoint() |
| Qdrant | qdrant | QdrantContainer | getGrpcHostAddress() |
| Weaviate | weaviate | WeaviateContainer | getHttpHostAddress() |
| Pinecone | pinecone | PineconeContainer | getEndpoint() |
| ChromaDB | chromadb | ChromaDBContainer | getEndpoint() |
| Typesense | typesense | TypesenseContainer | getHost() |
| Module | Artifact ID | Container Class | Use Case |
|---|---|---|---|
| LocalStack | localstack | LocalStackContainer | AWS service emulation |
| Azure | azure | AzuriteContainer | Azure Blob/Queue/Table storage |
| GCloud | gcloud | FirestoreEmulatorContainer, PubSubEmulatorContainer, BigtableEmulatorContainer | Google Cloud emulation |
| Vault | vault | VaultContainer | HashiCorp Vault secrets management |
| Consul | consul | ConsulContainer | Service discovery |
| MinIO | minio | MinIOContainer | S3-compatible object storage |
| K3s | k3s | K3sContainer | Lightweight Kubernetes |
| K6 | k6 | K6Container | Load testing |
| Module | Artifact ID | Container Class | Use Case |
|---|---|---|---|
| Selenium | selenium | BrowserWebDriverContainer | Browser automation |
| MockServer | mockserver | MockServerContainer | HTTP API mocking |
| Nginx | nginx | NginxContainer | Web server / reverse proxy |
| Toxiproxy | toxiproxy | ToxiproxyContainer | Network failure simulation |
| OpenFGA | openfga | OpenFGAContainer | Authorization service |
| Grafana | grafana | GrafanaContainer | Metrics visualization |
| LDAP | ldap | LdapContainer | LDAP server |
| Ollama | ollama | OllamaContainer | LLM inference |
| Presto | presto | PrestoContainer | Distributed SQL query |
| Trino | trino | TrinoContainer | Distributed SQL query |
| Timeplus | timeplus | TimeplusContainer | Stream processing |
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();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
}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();
}
}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();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 startupNoSQL 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();✅ 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!✅ 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);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>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.