{"id":22555503,"url":"https://github.com/quinnandrews/spring-local-postgresql","last_synced_at":"2026-04-16T19:02:45.760Z","repository":{"id":201115563,"uuid":"701087802","full_name":"quinnandrews/spring-local-postgresql","owner":"quinnandrews","description":"Decorates the Testcontainers PostgreSQL module with enhanced configuration for Spring Boot Applications. ","archived":false,"fork":false,"pushed_at":"2025-03-01T00:05:45.000Z","size":64,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-26T02:05:47.231Z","etag":null,"topics":["integration-testing","java","java-17","local-development","postgresql","spring","spring-boot","spring-boot-3","spring-testcontainers","testcontainers","testcontainers-postgres"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quinnandrews.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-10-05T22:23:10.000Z","updated_at":"2025-03-01T00:05:49.000Z","dependencies_parsed_at":"2024-01-18T05:29:39.921Z","dependency_job_id":"a87107da-3785-47eb-b58d-402e804ed340","html_url":"https://github.com/quinnandrews/spring-local-postgresql","commit_stats":null,"previous_names":["quinnandrews/spring-local-postgresql"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/quinnandrews/spring-local-postgresql","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quinnandrews%2Fspring-local-postgresql","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quinnandrews%2Fspring-local-postgresql/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quinnandrews%2Fspring-local-postgresql/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quinnandrews%2Fspring-local-postgresql/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quinnandrews","download_url":"https://codeload.github.com/quinnandrews/spring-local-postgresql/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quinnandrews%2Fspring-local-postgresql/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31899986,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-16T18:22:33.417Z","status":"ssl_error","status_checked_at":"2026-04-16T18:21:47.142Z","response_time":69,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["integration-testing","java","java-17","local-development","postgresql","spring","spring-boot","spring-boot-3","spring-testcontainers","testcontainers","testcontainers-postgres"],"created_at":"2024-12-07T19:08:06.522Z","updated_at":"2026-04-16T19:02:45.739Z","avatar_url":"https://github.com/quinnandrews.png","language":"Java","readme":"# Spring Local PostgreSQL\n\n## Description\nDecorates the Testcontainers PostgreSQL module with enhanced configuration for Spring Boot Applications. \n\nRequires minimal configuration using Spring conventions, but a variety of optional properties are provided to override default behavior by profile, supporting local development in addition to test execution.\n\n## Features\n- Configure whether the Testcontainers PostgreSQL module is active or not. Allows you to control its activation by profile.\n- Configure the Docker Image to use with the Testcontainers PostgreSQL module. Allows you to match the PostgreSQL version used in local and test environments with the version in production.\n- Configure the Testcontainers PostgreSQL module to run with a fixed container name. Useful for local development so that developers can easily find the running container.\n- Configure the Testcontainers PostgreSQL module to run with a fixed port. Useful for local development so that developers can connect using their JDBC client of choice with consistent, predictable configuration.\n- Configure whether to follow the Docker Container's log output. Useful for troubleshooting in some cases.\n- Configure the database name to match production.\n- Configure a database admin user to handle migration scripts and a second \"application user\" with restricted privileges, which the Application will use after migration is completed. \n- Configure an SQL script to run when the database in the container starts up.\n\n## Rationale\nWhen developing an Application that uses PostgreSQL in production, an embedded PostgreSQL server provides the benefits of using an in-memory database, like H2, but avoids the downsides. The database is spun up and torn down when the Application starts up and shuts down, but developers are able to utilize PostgreSQL features (that alternatives like H2 may not support) while test and local environments better resemble production. Development and testing become more effective and reliable.\n\nWhile Testcontainers is designed exclusively to support Integration Tests, this project is designed to support running the Application locally as well, reducing the overhead that would come with maintaining Testcontainers in addition to some other solution that fundamentally does the same thing. There is no need to maintain a local PostgreSQL server nor additional Docker configuration inside or outside the project.\n\n## Requirements\n### Java 17 \nhttps://adoptium.net/temurin/releases/?version=17\n\n### Docker\nhttps://www.docker.com/products/docker-desktop/ \u003cbr\u003e\nhttps://rancherdesktop.io/\n\nNOTE: Rancher Desktop may not work correctly if Docker Desktop had been previously installed.\n\n### PostgreSQL JDBC Driver\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.postgresql\u003c/groupId\u003e\n    \u003cartifactId\u003epostgresql\u003c/artifactId\u003e\n    \u003cscope\u003eruntime\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n\n### Spring Boot Starter JDBC or Spring Boot Start Data JPA\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-starter-jdbc\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eorg.springframework.boot\u003c/groupId\u003e\n    \u003cartifactId\u003espring-boot-starter-data-jpa\u003c/artifactId\u003e\n\u003c/dependency\u003e\n```\n\n## Transitive Dependencies\n- Spring Boot Starter Web 3.2.0\n- Spring Boot Configuration Processor 3.2.0\n- Spring Boot Starter Test 3.2.0\n- Spring Boot Testcontainers 3.2.0\n- Testcontainers PostgreSQL 1.19.3\n\n## Usage\n### Configuration as a Test Dependency\nWhile it is possible to declare `spring-local-postgresql` as a compile dependency, and control its activation with profiles, it is better practice to declare it as a test dependency. \n\nThis means, however, that all configuration for `spring-local-postgresql` (for both Integration Tests *and* for running the Application locally) can only reside in your project's test source. For Integration Tests this is common practice, but for running the Application locally it may seem unusual or perhaps difficult to do. However, by implementing the approach surfaced in this [article](https://bsideup.github.io/posts/local_development_with_testcontainers/) by Sergei Egorov, configuring a local profile in your project's test source becomes a simple process that will likely become a preferred practice as well.  \n\n### Add Spring Local PostgreSQL\nAdd the `spring-local-postgresql` artifact to your project as a test dependency:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003eio.github.quinnandrews\u003c/groupId\u003e\n    \u003cartifactId\u003espring-local-postgresql\u003c/artifactId\u003e\n    \u003cversion\u003e1.0.0\u003c/version\u003e\n    \u003cscope\u003etest\u003c/scope\u003e\n\u003c/dependency\u003e\n```\n(NOTE: The `spring-local-postgresql` artifact is NOT yet available in Maven Central, but is available from GitHub Packages, which requires additional configuration in your pom.xml file.)\n\n### Configure a Local Profile\nCreate a properties files in your test resources directory to configuration for a `local` profile. \n\nConfigure the `local` profile with a fixed container name, so that developers can quickly and consistently identify the running container.\n\nConfigure the `local` profile with a fixed port, so that developers can connect to the database with a consistent and predictable port (otherwise, their client's configuration will be invalidated every time the Application starts).\n\nSet other configuration properties as desired, or not at all to use default settings. \n\napplication-local.properties:\n```properties\nspring.local.postgresql.container.image=postgres:15\nspring.local.postgresql.container.name=local_postgresql\nspring.local.postgresql.container.port=15432\nspring.local.postgresql.database.name=pedals\nspring.local.postgresql.database.username=fuzz_local\nspring.local.postgresql.database.password=flange_local\nspring.local.postgresql.database.application.username=overdrive_local\nspring.local.postgresql.database.application.password=reverb_local\nspring.local.postgresql.database.init.script=data/init-local.sql\n```\n\nIn the example above, in addition to a fixed container name and port, the `local` profile has the following settings:\n- The `postgres:15` Docker Image is set to use a more recent version of PostgreSQL than the default (version 9) to match  production.\n- The `pedals` database name is set to match production, providing consistency for developers.\n- The `fuzz_local/flange_local` username/password pair is set as the admin user for migrations (using tools like Flyway) to match production behavior, but can also be used by developers with their client of choice.\n- The `overdrive_local/reverb_local` username/password pair is set as the application user to match production behavior, a user with limited privileges that the Application will use when executing queries with JPA and Hibernate. Developers can connect their client of choice with these credentials as well, to be consistent with the Application.  \n- The `data/init.sql` path is set to run a script in the resources directory that will create the application user and grant its schema privileges to match privileges of the corresponding user in production.\u003cbr/\u003e Example:\n    ```sql \n    CREATE USER overdrive_local WITH PASSWORD 'reverb_local';\n    GRANT USAGE ON SCHEMA public to overdrive_local;\n    GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public to overdrive_local;\n    ``` \n\n### Implement a Spring Boot Application Class to Run the Application with the Local Profile\nAdd a Spring Boot Application Class named `LocalDevApplication` to your project's test source, preferably in the same package as the Spring Boot Application Class in the main source, to mirror the convention of Test Classes residing in the same package as the Classes they test.    \n\nAnnotate `LocalDevApplication` with `@EnableLocalPostgreSQL` and `@Profile(\"local\")`. The `@EnableLocalPostgreSQL` activates configuration of the Testcontainers PostgreSQL module while `@Profile(\"local\")` ensures that configuration declared within the `LocalDevApplication` is only scanned and initialized if the `local` profile is active. \n\nInside the body of the `main` method, instantiate an instance of `SpringApplication` with the Application Class residing in the main source, to ensure that configuration in the main source is scanned. Then activate the `local` profile programmatically by calling `setAdditionalProfiles`. This will allow you to run `LocalDevApplication` in IntelliJ IDEA by simply right-clicking on the Class in the Project Panel and selecting `Run 'LocalDevApplication'` without having to add the `local` profile to the generated Spring Boot Run Configuration.\n\nLocalDevApplication.java:\n```java\n@EnableLocalPostgreSQL\n@Profile(\"local\")\n@SpringBootApplication\npublic class LocalDevApplication {\n\n    public static void main(final String[] args) {\n        final var springApplication = new SpringApplication(Application.class);\n        springApplication.setAdditionalProfiles(\"local\");\n        springApplication.run(args);\n    }\n}\n```\n### Configure a Test Profile\n\nConfigure the `test` profile to use a random container name and port by leaving their properties undeclared so that default settings will be used. Random names and ports are best practice for Integration Tests, and means that Integration Tests can be executed while the Application is running locally with the `local` profile.\n\nSet other configuration properties as desired, or not at all to use default settings.\n\napplication-test.properties:\n```properties\nspring.local.postgresql.container.image=postgres:15\nspring.local.postgresql.database.name=pedals\nspring.local.postgresql.database.username=fuzz_test\nspring.local.postgresql.database.password=flange_test\nspring.local.postgresql.database.application.username=overdrive_test\nspring.local.postgresql.database.application.password=reverb_test\nspring.local.postgresql.database.init.script=data/init-test.sql\n```\nIn the example above, the `test` profile has the following settings:\n- The `postgres:15` Docker Image is set to use a more recent version of PostgreSQL than the default (version 9) to match production.\n- The `pedals` database name is set to match production, providing consistency for tests.\n- The `fuzz_test/flange_test` username/password pair is set as the admin user for migrations (using tools like Flyway) to match production.\n- The `overdrive_test/reverb_test` username/password pair is set as the application user to match production, a user with limited privileges that Integration Tests will use when executing queries with JPA and Hibernate, making them more effective and reliable.\n- The `data/init.sql` path is set to run a script in the resources directory that will create the application user and grant its schema privileges to match privileges of the corresponding user in production.\u003cbr/\u003e Example:\n    ```sql \n    CREATE USER overdrive_test WITH PASSWORD 'reverb_test';\n    GRANT USAGE ON SCHEMA public to overdrive_test;\n    GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA public to overdrive_test;\n    ```\nNOTE: One can, of course, configure the test profile and local profile to use the same username/password pairs, but using distinct pairs is recommended, in order to isolate environments and lower the risk of potential issues.\n\n#### Implement an Integration Test\n\nAdd an Integration Test Class. Annotate with `@EnableLocalPostgreSQL`, `@ActiveProfiles(\"test\")` and `@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)`. The `@EnableLocalPostgreSQL` activates configuration of the Testcontainers PostgreSQL module. The `@ActiveProfiles(\"test\")` will activate the `test` profile when executed. And the `@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)`.\n\nWrite a test. The example below uses the RestAssured framework to call a REST endpoint backed by the PostgreSQL Container.\n\nExample:\n\n```java\n@EnableLocalPostgreSQL\n@ActiveProfiles(\"test\")\n@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)\npublic class GuitarPedalControllerTest {\n\n    @LocalServerPort\n    private Integer port;\n\n    @Test\n    void getAllGuitarPedals()  {\n        given().port(port)\n                .when().get(\"/guitar-pedals\")\n                .then().statusCode(HttpStatus.OK.value())\n                .and().contentType(ContentType.JSON)\n                .and().body(\"size()\", equalTo(4))\n                .and().body(\"guitarPedalName\", hasItems(\n                        \"Big Muff Fuzz\",\n                        \"Deco: Tape Saturation and Double Tracker\",\n                        \"Soft Focus Reverb\",\n                        \"Sneak Attack: Attack/Decay and Tremolo\"))\n                .and().body(\"dateSold\", hasItems(null, null, null, \"2023-03-21\"));\n    }\n}\n```\nNOTE: It is, of course, possible to declare `@EnableLocalPostgreSQL` in a Spring Boot Application Class, named `TestApplication`, for example, so that one does not have to add `@EnableLocalPostgreSQL` to every test Class, and that may be appropriate in some cases, but in general it is recommended that each test Class controls the declaration of the resources it needs. After all, some test Classes may need both PostgreSQL and Kafka, for instance, while other test Classes may only need one or the other. In such a case, initializing PostgreSQL and Kafka containers for all test Classes would waste resources and prolong the time it takes for all test Classes to run. \n\n## Supported Configuration Properties\n**spring.local.postgresql.engaged**\u003cbr/\u003e\nWhether the containerized PostgreSQL database should be configured and started when the Application starts. By default, it is set to `true`. To disengage, set to `false`.\n    \n**spring.local.postgresql.container.image**\u003cbr/\u003e\nThe Docker Image with the chosen version of PostgreSQL (example: `postgres:15`). If undefined, Testcontainers will use its default (`postgres:9.6.12`). \n\n**spring.local.postgresql.container.name**\u003cbr/\u003e\nThe name to use for the Docker Container when started. If undefined, a random name is used. Random names are preferred for Integration Tests, but when running the Application locally, a fixed name is useful, since it allows developers to find the running container with a consistent, predictable name.\n    \n**spring.local.postgresql.container.port**\u003cbr/\u003e\nThe port on the Docker Container to map with the PostgreSQL port inside the container. If undefined, a random port is used. Random ports are preferred for Integration Tests, but when running the Application locally, a fixed port is useful, since it allows developers to configure any connecting, external tools or apps with a consistent, predictable port.\n\n**spring.local.postgresql.container.log.follow**\u003cbr/\u003e\nWhether the Application should log the output produced by the container's log. By default, container logs are not followed. Set with `true` to see their output.\n\n**spring.local.postgresql.database.name**\u003cbr/\u003e\nThe name to use for the PostgreSQL database. If undefined, Testcontainers will use its default (`test`).\n\n**spring.local.postgresql.database.username**\u003cbr/\u003e\nThe username of an admin or superuser in the PostgreSQL database. If `spring.local.postgresql.database.application.username` is not defined, this will also be the username the Application uses to connect. If undefined, Testcontainers will use its default (`test`).\n\n**spring.local.postgresql.database.password**\u003cbr/\u003e\nThe password that goes with the username of the admin or superuser in the PostgreSQL database. If `spring.local.postgresql.database.application.username` is not defined, this will also be the password for the username the Application uses to connect. If undefined, Testcontainers will use its default (`test`).\n\n**spring.local.postgresql.database.application.username**\u003cbr/\u003e\nIn most cases the database user used by the Application should not have admin or superuser privileges. This property provides the ability to define the username of an \"application user\" for use during testing and local development. The Application will use this username to connect to the PostgreSQL database. If undefined, the value defined by `spring.local.postgresql.database.username` will be used instead. NOTE: The application user will NOT be created automatically. An init-script is required to create the user and grant their initial privileges.\n\n**spring.local.postgresql.database.application.password**\u003cbr/\u003e\nIn most cases the database user used by the Application should not have admin or superuser privileges. This property provides the ability to define the password for the username of an \"application user\" for use during testing and local development. The Application will use this password to connect to the PostgreSQL database. If undefined, the value defined by `spring.local.postgresql.database.password` will be used instead. NOTE: The application user will NOT be created automatically. An init-script is required to create the user and grant their initial privileges.\n\n**spring.local.postgresql.database.init.script**\u003cbr/\u003e\nThe path to an SQL file (with the `resources` directory as the root) that should be executed when the Docker Container starts. Executes before migrations. Useful for administrative tasks, like creating additional users, for example. If undefined, no script is executed.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquinnandrews%2Fspring-local-postgresql","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquinnandrews%2Fspring-local-postgresql","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquinnandrews%2Fspring-local-postgresql/lists"}