This project is a fork of Zonkyio Embedded PostgreSQL which is a fork of OpenTable Embedded PostgreSQL Component created back in 2018. The original project continues, but with a very different philosophy - wrapping the postgres instance in a docker container. Whereas this project follows the original approach of using native postgres binaries running directly on the target platform without the overhead of virtualization.
This fork also differs from the Zonkyio fork in the sense that it depends on the latest LTS version of Java, migrates from the legacy File to the modern Path, has full javadoc coverage, drops no longer needed dependencies, and drops legacy JUnit 4 support. Think of this as a comprehensive modernization.
The library allows embedding PostgreSQL into Java application code with no external dependencies. Excellent for allowing you to unit test with a "real" Postgres without requiring end users to install and set up a database cluster.
- All features of
com.opentable:otj-pg-embedded:0.13.3 - Configurable version of PostgreSQL binaries
- PostgreSQL 11+ support even for Linux platform
- Support for running inside Docker, including Alpine Linux
To use this with Gradle, add the following to your build.gradle.kts:
dependencies {
testImplementation(libs.embeddedPostgres)
}And the following to your gradle/libs.versions.toml:
[versions]
# Check this on https://central.sonatype.com/artifact/com.smushytaco/embedded-postgres/
embeddedPostgres = "3.0.2"
[libraries]
embeddedPostgres = { group = "com.smushytaco", name = "embedded-postgres", version.ref = "embeddedPostgres" }The default version of the embedded postgres is PostgreSQL 18.1.0, but you can change it by following the instructions described in Postgres version.
In your JUnit test just add:
@RegisterExtension
final SingleInstancePostgresExtension pg = EmbeddedPostgresExtension.singleInstance();This simply has JUnit manage an instance of EmbeddedPostgres (start, stop). You can then use this to get a DataSource with: pg.getEmbeddedPostgres().getPostgresDatabase();
Additionally, you may use the EmbeddedPostgres class directly by manually starting and stopping the instance; see EmbeddedPostgresTest for an example.
Default username/password is: postgres/postgres and the default database is 'postgres'
You can easily integrate Flyway or Liquibase database schema migration:
@RegisterExtension
final PreparedDbExtension db = EmbeddedPostgresExtension.preparedDatabase(FlywayPreparer.forClasspathLocation("db/my-db-schema"));@RegisterExtension
final PreparedDbExtension db = EmbeddedPostgresExtension.preparedDatabase(LiquibasePreparer.forClasspathLocation("liqui/master.xml"));This will create an independent database for every test with the given schema loaded from the classpath. Database templates are used so the time cost is relatively small, given the superior isolation truly independent databases gives you.
The default version of the embedded postgres is PostgreSQL 18.1.0, but it can be changed by importing embedded-postgres-binaries-bom.
Add the following to your build.gradle.kts;
dependencies {
testImplementation(enforcedPlatform(libs.postgresql))
}And the following to your gradle/libs.versions.toml:
[versions]
# Check this on https://central.sonatype.com/artifact/io.zonky.test.postgres/embedded-postgres-binaries-bom/
postgresql = "18.1.0"
[libraries]
postgresql = { group = "io.zonky.test.postgres", name = "embedded-postgres-binaries-bom", version.ref = "postgresql" }A list of all available versions of postgres binaries can be found here.
Note that the release cycle of the postgres binaries is independent of the release cycle of this library, so you can upgrade to a new version of postgres binaries immediately after it is released.
By default, only the support for amd64 architecture is enabled.
Support for other architectures can be enabled by adding the corresponding Maven dependencies as shown in the example below:
Add the following to your build.gradle.kts;
dependencies {
testImplementation(libs.embeddedPostgresBinaries.linux.i386)
}And the following to your gradle/libs.versions.toml:
[libraries]
embeddedPostgresBinaries-linux-i386 = { group = "io.zonky.test.postgres", name = "embedded-postgres-binaries-linux-i386" }Supported platforms: Darwin, Windows, Linux, Alpine Linux
Supported architectures: amd64, i386, arm32v6, arm32v7, arm64v8, ppc64le
Note that not all architectures are supported by all platforms, look here for an exhaustive list of all available artifacts.
Since PostgreSQL 10.0, there are additional artifacts with alpine-lite suffix. These artifacts contain postgres binaries for Alpine Linux with disabled ICU support for further size reduction.
Try to clean up the /tmp/embedded-pg/PG-XYZ directory containing temporary binaries of the embedded database.
You probably need to install Microsoft Visual C++ 2013 Redistributable Package. The version 2013 is important, installation of other versions will not help. More detailed is the problem discussed here.
Running builds inside a Docker container is fully supported, including Alpine Linux. However, PostgreSQL has a restriction the database process must run under a non-root user. Otherwise, the database does not start and fails with an error.
Below are some examples of how to prepare a docker image running with a non-root user:
Standard Dockerfile
FROM openjdk:8-jdk
RUN groupadd --system --gid 1000 test
RUN useradd --system --gid test --uid 1000 --shell /bin/bash --create-home test
USER test
WORKDIR /home/testAlpine Dockerfile
FROM openjdk:8-jdk-alpine
RUN addgroup -S -g 1000 test
RUN adduser -D -S -G test -u 1000 -s /bin/ash test
USER test
WORKDIR /home/testGitlab runner Docker executor
Configure Docker container to run in privileged mode as described here.
[[runners]]
executor = "docker"
[runners.docker]
privileged = true
If the above do not resolve your error, verify that the correct locales are available in your container. For example, many variants of AlmaLinux:9 do not come with glibc-langpack-en. This will lead to misleading errors during initdb. Additionally, you can optionally set your locale with setLocaleConfig() when building your EmbeddedPostgres instance.
The project is released under version 2.0 of the Apache License.