How to Run a Postgres Container for Tests With Testcontainers in CI
PostgreSQLContainer starts a real Postgres and exposes a getJdbcUrl that already points at the ephemeral mapped port.
Use the postgresql module container so you do not hand-roll env vars and wait logic. It waits for readiness and gives you a JDBC URL, username, and password to connect.
Steps
- Add the
postgresqlTestcontainers module. - Instantiate
PostgreSQLContainerwith a pinned tag. - Read
getJdbcUrl(),getUsername(),getPassword()in your test. - Optionally set a database name, user, and init script.
Java example
PostgresIT.java
@Container
static PostgreSQLContainer<?> db =
new PostgreSQLContainer<>("postgres:16-alpine")
.withDatabaseName("app")
.withUsername("app")
.withPassword("secret");
@DynamicPropertySource
static void props(DynamicPropertyRegistry r) {
r.add("spring.datasource.url", db::getJdbcUrl);
r.add("spring.datasource.username", db::getUsername);
r.add("spring.datasource.password", db::getPassword);
}Python example
test_db.py
from testcontainers.postgres import PostgresContainer
with PostgresContainer("postgres:16-alpine") as pg:
url = pg.get_connection_url() # postgresql+psycopg2://.../testGotchas
- Do not hardcode 5432; use the mapped port from the JDBC URL or
getMappedPort(5432). - The module already waits for Postgres to accept connections, so no manual sleep is needed.
Related guides
How to Run Database Migrations Before Testcontainers TestsApply Flyway or Liquibase migrations against a Testcontainers database before tests run, or use init scripts,…
How to Set Up Testcontainers for Java and JUnit in CIWire Testcontainers into a Java/JUnit 5 project and run it on GitHub-hosted runners, where Docker is already…