Testcontainers implementation for MariaDB - provides lightweight, throwaway instances of MariaDB databases for Java testing
Core container functionality for creating and managing MariaDB instances with JDBC connectivity. Provides database connection details, lifecycle management, and MariaDB-specific configuration options.
Creates a new MariaDB container instance with specified Docker image.
/**
* Creates MariaDB container with default image (deprecated)
* @deprecated Use MariaDBContainer(DockerImageName) instead
*/
@Deprecated
public MariaDBContainer();
/**
* Creates MariaDB container with specified image name
* @param dockerImageName Docker image name as string (e.g., "mariadb:10.3.39")
*/
public MariaDBContainer(String dockerImageName);
/**
* Creates MariaDB container with DockerImageName object
* @param dockerImageName DockerImageName with version compatibility validation
*/
public MariaDBContainer(DockerImageName dockerImageName);Usage Examples:
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.utility.DockerImageName;
// Recommended approach with DockerImageName
MariaDBContainer<?> mariadb = new MariaDBContainer<>(
DockerImageName.parse("mariadb:10.3.39")
);
// Alternative with string image name
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:11.2.4");
// Start the container
mariadb.start();Retrieves connection details and JDBC configuration for the running container.
/**
* Returns JDBC connection URL for the MariaDB container
* @return JDBC URL with host, port, database name, and URL parameters
*/
public String getJdbcUrl();
/**
* Returns the MariaDB JDBC driver class name
* @return "org.mariadb.jdbc.Driver"
*/
public String getDriverClassName();
/**
* Returns the configured database name
* @return Database name (default: "test")
*/
public String getDatabaseName();
/**
* Returns the configured database username
* @return Username (default: "test")
*/
public String getUsername();
/**
* Returns the configured database password
* @return Password (default: "test")
*/
public String getPassword();
/**
* Returns the test query string for connection validation
* @return "SELECT 1"
*/
public String getTestQueryString();Usage Examples:
try (MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")) {
mariadb.start();
// Get connection information
String url = mariadb.getJdbcUrl();
String user = mariadb.getUsername();
String pass = mariadb.getPassword();
String driver = mariadb.getDriverClassName();
// Use with DriverManager
Connection conn = DriverManager.getConnection(url, user, pass);
// Or with DataSource configuration
HikariConfig config = new HikariConfig();
config.setJdbcUrl(url);
config.setUsername(user);
config.setPassword(pass);
config.setDriverClassName(driver);
}Configures database name, credentials, and MariaDB-specific settings.
/**
* Sets the database name to create in the container
* @param databaseName Name of database to create
* @return Container instance for method chaining
*/
public SELF withDatabaseName(String databaseName);
/**
* Sets the database username
* @param username Database username (cannot be empty if not "root")
* @return Container instance for method chaining
*/
public SELF withUsername(String username);
/**
* Sets the database password
* @param password Database password (can be empty only for root user)
* @return Container instance for method chaining
*/
public SELF withPassword(String password);
/**
* Sets custom MariaDB configuration override directory
* @param configPath Path to directory containing MariaDB configuration files
* @return Container instance for method chaining
*/
public SELF withConfigurationOverride(String configPath);Usage Examples:
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withDatabaseName("myapp")
.withUsername("appuser")
.withPassword("secretpass")
.withConfigurationOverride("path/to/mariadb-config");
// Root user with empty password (allowed)
MariaDBContainer<?> rootContainer = new MariaDBContainer<>("mariadb:11.2.4")
.withUsername("root"); // Empty password automatically allowed for root
// Custom JDBC URL parameters
MariaDBContainer<?> customContainer = new MariaDBContainer<>("mariadb:10.3.39")
.withUrlParam("connectTimeout", "40000")
.withUrlParam("rewriteBatchedStatements", "true");Container startup, health checks, resource management, and operational commands.
/**
* Returns port numbers used for container liveness checks
* @return Set containing MariaDB port (3306)
*/
public Set<Integer> getLivenessCheckPortNumbers();
/**
* Starts the container (inherited from GenericContainer)
*/
public void start();
/**
* Stops the container (inherited from GenericContainer)
*/
public void stop();
/**
* Checks if the container is currently running
* @return true if container is running
*/
public boolean isRunning();
/**
* Gets the host that can be used to connect to the container
* @return Host address for container access
*/
public String getHost();
/**
* Gets the mapped host port for a container port
* @param originalPort Container port number
* @return Mapped host port number
*/
public Integer getMappedPort(int originalPort);
/**
* Returns container ID if container is running
* @return Container ID string
*/
public String getContainerId();Usage Examples:
// JUnit 5 integration
@Testcontainers
class MariaDBIntegrationTest {
@Container
static MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withDatabaseName("testdb")
.withUsername("testuser")
.withPassword("testpass");
@Test
void testDatabaseConnection() throws SQLException {
// Container automatically started by JUnit
String jdbcUrl = mariadb.getJdbcUrl();
try (Connection conn = DriverManager.getConnection(
jdbcUrl, mariadb.getUsername(), mariadb.getPassword())) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT 1");
assertTrue(rs.next());
assertEquals(1, rs.getInt(1));
}
}
}
// Manual lifecycle management
try (MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")) {
mariadb.start();
// Container is running, perform tests
performDatabaseTests(mariadb);
// Container automatically stopped when exiting try-with-resources
}Execute commands within the container and manage files for database maintenance and debugging.
/**
* Executes command inside the running container
* @param command Command and arguments to execute
* @return ExecResult containing exit code, stdout, and stderr
*/
public Container.ExecResult execInContainer(String... command) throws IOException, InterruptedException;
/**
* Executes command with specific output charset
* @param outputCharset Character encoding for command output
* @param command Command and arguments to execute
* @return ExecResult with decoded output
*/
public Container.ExecResult execInContainer(Charset outputCharset, String... command) throws IOException, InterruptedException;
/**
* Copies file from host to container
* @param mountableFile File to copy (from classpath or filesystem)
* @param containerPath Destination path in container
*/
public void copyFileToContainer(MountableFile mountableFile, String containerPath);
/**
* Copies file from container to host
* @param containerPath Source path in container
* @param destinationPath Destination path on host
*/
public void copyFileFromContainer(String containerPath, String destinationPath) throws IOException, InterruptedException;
/**
* Gets container logs
* @return Complete container log output
*/
public String getLogs();
/**
* Gets filtered container logs
* @param types Output types to include (STDOUT, STDERR)
* @return Filtered log output
*/
public String getLogs(OutputFrame.OutputType... types);Usage Examples:
try (MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")) {
mariadb.start();
// Execute SQL command directly via MySQL CLI
Container.ExecResult result = mariadb.execInContainer(
"mysql", "-u", mariadb.getUsername(), "-p" + mariadb.getPassword(),
"-e", "SHOW DATABASES;"
);
System.out.println("Databases: " + result.getStdout());
// Copy backup file to container
MountableFile backupFile = MountableFile.forClasspathResource("backup.sql");
mariadb.copyFileToContainer(backupFile, "/tmp/backup.sql");
// Restore from backup
Container.ExecResult restoreResult = mariadb.execInContainer(
"mysql", "-u", mariadb.getUsername(), "-p" + mariadb.getPassword(),
mariadb.getDatabaseName(), "-e", "source /tmp/backup.sql"
);
// Export database dump
Container.ExecResult dumpResult = mariadb.execInContainer(
"mysqldump", "-u", mariadb.getUsername(), "-p" + mariadb.getPassword(),
mariadb.getDatabaseName()
);
// Copy dump to host
try (FileWriter writer = new FileWriter("database-dump.sql")) {
writer.write(dumpResult.getStdout());
}
// Get container logs for debugging
String logs = mariadb.getLogs();
System.out.println("Container logs: " + logs);
}Sets up database schema and data when the container starts, supporting SQL scripts and programmatic initialization.
/**
* Sets a single initialization script to run on container startup
* @param initScriptPath Path to SQL script file (classpath or file system)
* @return Container instance for method chaining
*/
public SELF withInitScript(String initScriptPath);
/**
* Sets multiple initialization scripts to run in order on container startup
* @param initScriptPaths Paths to SQL script files
* @return Container instance for method chaining
*/
public SELF withInitScripts(String... initScriptPaths);
/**
* Sets multiple initialization scripts from a collection
* @param initScriptPaths Collection of script paths
* @return Container instance for method chaining
*/
public SELF withInitScripts(Iterable<String> initScriptPaths);Usage Examples:
// Single initialization script
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withDatabaseName("myapp")
.withInitScript("schema.sql");
// Multiple initialization scripts (executed in order)
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withInitScripts("schema.sql", "data.sql", "indexes.sql");
// Scripts from classpath
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withInitScript("classpath:db/migration/V1__create_tables.sql");
mariadb.start();
// Verify initialization worked
try (Connection conn = DriverManager.getConnection(
mariadb.getJdbcUrl(), mariadb.getUsername(), mariadb.getPassword())) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT COUNT(*) FROM users");
rs.next();
int userCount = rs.getInt(1);
System.out.println("Initialized with " + userCount + " users");
}Configures container startup and database connection timeouts for reliable operation.
/**
* Sets container startup timeout in seconds
* @param startupTimeoutSeconds Maximum time to wait for container startup
* @return Container instance for method chaining
*/
public SELF withStartupTimeoutSeconds(int startupTimeoutSeconds);
/**
* Sets database connection timeout in seconds
* @param connectTimeoutSeconds Maximum time to wait for database connection
* @return Container instance for method chaining
*/
public SELF withConnectTimeoutSeconds(int connectTimeoutSeconds);Usage Examples:
// Increase timeouts for slow environments
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withStartupTimeoutSeconds(300) // 5 minutes for container startup
.withConnectTimeoutSeconds(60); // 1 minute for database connection
// Critical for CI/CD environments with resource constraints
MariaDBContainer<?> ciMariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withStartupTimeoutSeconds(600)
.withConnectTimeoutSeconds(120);
ciMariadb.start();Overrides the default MariaDB startup command for custom server configuration.
/**
* Overrides the container command (inherited from GenericContainer)
* @param command Command arguments to pass to MariaDB server
* @return Container instance for method chaining
*/
public SELF withCommand(String... command);Usage Examples:
// Override MariaDB server settings via command line
MariaDBContainer<?> customMariaDB = new MariaDBContainer<>("mariadb:10.3.39")
.withCommand("mysqld --auto_increment_increment=10 --max_connections=200");
customMariaDB.start();
// Verify the custom configuration
try (Connection conn = DriverManager.getConnection(
customMariaDB.getJdbcUrl(),
customMariaDB.getUsername(),
customMariaDB.getPassword())) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SHOW VARIABLES LIKE 'auto_increment_increment'");
rs.next();
assertEquals("10", rs.getString("Value"));
}The MariaDB container automatically configures these environment variables:
// Automatically set based on configuration
private static final String MYSQL_DATABASE = "MYSQL_DATABASE"; // Database name
private static final String MYSQL_USER = "MYSQL_USER"; // Username (if not root)
private static final String MYSQL_PASSWORD = "MYSQL_PASSWORD"; // User password
private static final String MYSQL_ROOT_PASSWORD = "MYSQL_ROOT_PASSWORD"; // Root password
private static final String MYSQL_ALLOW_EMPTY_PASSWORD = "MYSQL_ALLOW_EMPTY_PASSWORD"; // Empty password for rootCustom MariaDB configuration can be provided through volume mounting:
// Configuration parameter for custom config directory
private static final String MY_CNF_CONFIG_OVERRIDE_PARAM_NAME = "TC_MY_CNF";
// Configuration mounted to container at:
// /etc/mysql/conf.d (MariaDB configuration directory)Usage Example:
// Place custom configuration files in src/test/resources/mariadb-config/
// Files like custom.cnf will be mounted to /etc/mysql/conf.d/
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withConfigurationOverride("mariadb-config");Common exceptions and troubleshooting guide for MariaDB container issues:
Cause: MariaDB JDBC driver not in classpath.
Solution: Add the MariaDB JDBC driver dependency:
testImplementation 'org.mariadb.jdbc:mariadb-java-client:3.4.1'Cause: Container failed to start (Docker issues, port conflicts, resource constraints).
Solutions:
// Increase startup timeout for slow environments
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withStartupTimeoutSeconds(300);
// Check Docker daemon status and available resources
// Ensure port 3306 is not in use by another processCause: Container takes too long to become ready.
Solutions:
// Increase timeout and retry attempts
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withStartupTimeoutSeconds(600)
.withStartupAttempts(3);Cause: Database not ready or connection configuration issues.
Solutions:
// Increase connection timeout
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withConnectTimeoutSeconds(120);
// Verify container is running before connecting
assertTrue(mariadb.isRunning());
// Use container-provided connection details
String jdbcUrl = mariadb.getJdbcUrl(); // Don't hardcode connection detailsCause: Custom configuration files have wrong permissions.
Solution:
// Ensure configuration directory is readable
// Set proper file permissions on src/test/resources/mariadb-config/
// Use try-with-resources for proper cleanupCause: Non-root user with empty password.
Solution:
// Only root user can have empty password
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withUsername("root"); // Empty password allowed for root
// For other users, always provide password
MariaDBContainer<?> mariadb = new MariaDBContainer<>("mariadb:10.3.39")
.withUsername("testuser")
.withPassword("testpass"); // Required for non-root userspublic static final String NAME = "mariadb"; // Container type identifier
public static final Integer MARIADB_PORT = 3306; // MariaDB default port
// Note: DEFAULT_USER and DEFAULT_PASSWORD are package-private, not public API
@Deprecated
public static final String DEFAULT_TAG = "10.3.6"; // Deprecated default version
@Deprecated
public static final String IMAGE = "mariadb"; // Deprecated image nameInstall with Tessl CLI
npx tessl i tessl/maven-org-testcontainers--mariadb