diff --git a/docs/modules/databases/jdbc.md b/docs/modules/databases/jdbc.md
index 7adaf2f5e70..d402b5983b4 100644
--- a/docs/modules/databases/jdbc.md
+++ b/docs/modules/databases/jdbc.md
@@ -39,6 +39,10 @@ Insert `tc:` after `jdbc:` as follows. Note that the hostname, port and database
`jdbc:tc:postgis:9.6-2.5:///databasename`
+#### Using TimescaleDB
+
+`jdbc:tc:timescaldb:2.1.0-pg13:///databasename`
+
#### Using Trino
`jdbc:tc:trino:352://localhost/memory/default`
diff --git a/modules/jdbc-test/src/main/java/org/testcontainers/jdbc/AbstractJDBCDriverTest.java b/modules/jdbc-test/src/main/java/org/testcontainers/jdbc/AbstractJDBCDriverTest.java
index 38ca2237567..580aad513e3 100644
--- a/modules/jdbc-test/src/main/java/org/testcontainers/jdbc/AbstractJDBCDriverTest.java
+++ b/modules/jdbc-test/src/main/java/org/testcontainers/jdbc/AbstractJDBCDriverTest.java
@@ -117,7 +117,9 @@ private void performTestForJDBCParamUsage(HikariDataSource dataSource) throws SQ
String databaseQuery = "SELECT DATABASE()";
// Postgres does not have Database() as a function
String databaseType = ConnectionUrl.newInstance(jdbcUrl).getDatabaseType();
- if (databaseType.equalsIgnoreCase("postgresql") || databaseType.equalsIgnoreCase("postgis")) {
+ if (databaseType.equalsIgnoreCase("postgresql") ||
+ databaseType.equalsIgnoreCase("postgis") ||
+ databaseType.equalsIgnoreCase("timescaledb")) {
databaseQuery = "SELECT CURRENT_DATABASE()";
}
diff --git a/modules/postgresql/src/main/java/org/testcontainers/containers/TimescaleDBContainerProvider.java b/modules/postgresql/src/main/java/org/testcontainers/containers/TimescaleDBContainerProvider.java
new file mode 100644
index 00000000000..c9b81fccfe4
--- /dev/null
+++ b/modules/postgresql/src/main/java/org/testcontainers/containers/TimescaleDBContainerProvider.java
@@ -0,0 +1,39 @@
+package org.testcontainers.containers;
+
+import org.testcontainers.jdbc.ConnectionUrl;
+import org.testcontainers.utility.DockerImageName;
+
+/**
+ * Factory for TimescaleDB containers, which are a special flavour of PostgreSQL.
+ *
+ * @see https://docs.timescale.com/latest/introduction
+ */
+public class TimescaleDBContainerProvider extends JdbcDatabaseContainerProvider {
+
+ private static final String NAME = "timescaledb";
+ private static final String DEFAULT_TAG = "2.1.0-pg11";
+ private static final DockerImageName DEFAULT_IMAGE = DockerImageName.parse("timescale/timescaledb").asCompatibleSubstituteFor("postgres");
+ public static final String USER_PARAM = "user";
+ public static final String PASSWORD_PARAM = "password";
+
+
+ @Override
+ public boolean supports(String databaseType) {
+ return databaseType.equals(NAME);
+ }
+
+ @Override
+ public JdbcDatabaseContainer newInstance() {
+ return newInstance(DEFAULT_TAG);
+ }
+
+ @Override
+ public JdbcDatabaseContainer newInstance(String tag) {
+ return new PostgreSQLContainer(DEFAULT_IMAGE.withTag(tag));
+ }
+
+ @Override
+ public JdbcDatabaseContainer newInstance(ConnectionUrl connectionUrl) {
+ return newInstanceFromConnectionUrl(connectionUrl, USER_PARAM, PASSWORD_PARAM);
+ }
+}
diff --git a/modules/postgresql/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider b/modules/postgresql/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider
index 79b2f29340a..05df9054522 100644
--- a/modules/postgresql/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider
+++ b/modules/postgresql/src/main/resources/META-INF/services/org.testcontainers.containers.JdbcDatabaseContainerProvider
@@ -1,2 +1,3 @@
org.testcontainers.containers.PostgreSQLContainerProvider
org.testcontainers.containers.PostgisContainerProvider
+org.testcontainers.containers.TimescaleDBContainerProvider
diff --git a/modules/postgresql/src/test/java/org/testcontainers/containers/TimescaleDBContainerTest.java b/modules/postgresql/src/test/java/org/testcontainers/containers/TimescaleDBContainerTest.java
new file mode 100644
index 00000000000..f3c73a4111b
--- /dev/null
+++ b/modules/postgresql/src/test/java/org/testcontainers/containers/TimescaleDBContainerTest.java
@@ -0,0 +1,58 @@
+package org.testcontainers.containers;
+
+import org.junit.Test;
+import org.testcontainers.db.AbstractContainerDatabaseTest;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;
+import static org.rnorth.visibleassertions.VisibleAssertions.assertNotEquals;
+
+public class TimescaleDBContainerTest extends AbstractContainerDatabaseTest {
+
+ @Test
+ public void testSimple() throws SQLException {
+ try (JdbcDatabaseContainer> postgres = new TimescaleDBContainerProvider().newInstance()) {
+ postgres.start();
+
+ ResultSet resultSet = performQuery(postgres, "SELECT 1");
+ int resultSetInt = resultSet.getInt(1);
+ assertEquals("A basic SELECT query succeeds", 1, resultSetInt);
+ }
+ }
+
+ @Test
+ public void testCommandOverride() throws SQLException {
+ try (GenericContainer> postgres = new TimescaleDBContainerProvider().newInstance().withCommand("postgres -c max_connections=42")) {
+ postgres.start();
+
+ ResultSet resultSet = performQuery((JdbcDatabaseContainer>) postgres, "SELECT current_setting('max_connections')");
+ String result = resultSet.getString(1);
+ assertEquals("max_connections should be overriden", "42", result);
+ }
+ }
+
+ @Test
+ public void testUnsetCommand() throws SQLException {
+ try (GenericContainer> postgres = new TimescaleDBContainerProvider().newInstance().withCommand("postgres -c max_connections=42").withCommand()) {
+ postgres.start();
+
+ ResultSet resultSet = performQuery((JdbcDatabaseContainer>) postgres, "SELECT current_setting('max_connections')");
+ String result = resultSet.getString(1);
+ assertNotEquals("max_connections should not be overriden", "42", result);
+ }
+ }
+
+ @Test
+ public void testExplicitInitScript() throws SQLException {
+ try (JdbcDatabaseContainer> postgres = new TimescaleDBContainerProvider().newInstance().withInitScript("somepath/init_timescaledb.sql")) {
+ postgres.start();
+
+ ResultSet resultSet = performQuery(postgres, "SELECT foo FROM bar");
+
+ String firstColumnValue = resultSet.getString(1);
+ assertEquals("Value from init script should equal real value", "hello world", firstColumnValue);
+ }
+ }
+}
diff --git a/modules/postgresql/src/test/java/org/testcontainers/jdbc/timescaledb/TimescaleDBJDBCDriverTest.java b/modules/postgresql/src/test/java/org/testcontainers/jdbc/timescaledb/TimescaleDBJDBCDriverTest.java
new file mode 100644
index 00000000000..8a6eaa3d04b
--- /dev/null
+++ b/modules/postgresql/src/test/java/org/testcontainers/jdbc/timescaledb/TimescaleDBJDBCDriverTest.java
@@ -0,0 +1,22 @@
+package org.testcontainers.jdbc.timescaledb;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.testcontainers.jdbc.AbstractJDBCDriverTest;
+
+import java.util.EnumSet;
+
+import static java.util.Arrays.asList;
+
+@RunWith(Parameterized.class)
+public class TimescaleDBJDBCDriverTest extends AbstractJDBCDriverTest {
+
+ @Parameterized.Parameters(name = "{index} - {0}")
+ public static Iterable