Version: Spring Boot 3.1

application.yml:

spring:
  docker:
    compose:
      file: "./docker-compose.yml"
  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://localhost:15432/platform_db?currentSchema=application
    username: postgres
    password: example

If I do not include:

implementation 'org.springframework.boot:spring-boot-docker-compose'

then when I start the app, Spring uses the correct JDBC url. Note I have providing a specific database and schema.

When I include docker-compose support, HikariCP ignores my configuration:

DEBUG com.zaxxer.hikari.HikariConfig.logConfiguration[1132] - jdbcUrl.........................jdbc:postgresql://127.0.0.1:15432/postgres

and the application fails to run because it's ignoring my JDBC url.

Thanks

Comment From: wilkinsona

Assuming that you have an SQL database configured in ./docker-compose.yml, the behavior that you have described is expected. Service connections from containers managed by Docker Compose or Testcontainers take priority over application property-based configuration.

Comment From: GrantGochnauer

@wilkinsona Thanks. Is there any documentation available about moving property based configurations (like JDBC url) to the docker-compose file so that Spring will pick up those values from the compose file? Thank you!

Comment From: wilkinsona

It doesn't really make sense to move the JDBC URL to the compose file as they're two competing sources of the information that's required to connect to the database.

Boot will honour the environment variables that the container supports. For example, if you configure POSTGRES_DB this will be used when creating the JDBC URL:

https://github.com/spring-projects/spring-boot/blob/6a74f6314344ba4f2e99c2ef96f3bf36c78feb81/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresEnvironment.java#L39-L43

https://github.com/spring-projects/spring-boot/blob/6a74f6314344ba4f2e99c2ef96f3bf36c78feb81/spring-boot-project/spring-boot-docker-compose/src/main/java/org/springframework/boot/docker/compose/service/connection/postgres/PostgresJdbcDockerComposeConnectionDetailsFactory.java#L60

Can you describe what you're trying to do?

Comment From: GrantGochnauer

Sure -

We have a postgres database that we want to start via docker-compose when starting our app for local development. Inside the docker image, we have a postgres database that is using an application specific database name "platform_db" with a specific schema name "application". Previously when we used the properties to configure the JDBC url, we could provide these values to Spring on startup so that when the connection pool was created, it defaulted to the custom postgres database and schema.

With docker-compose support enabled, Spring ignores our configured database and schema names and tries to connect to our docker postgres instance using the "postgres" database and default schema - which is a default setting. So we are then unable to connect to our database in our application when using the docker-compose addon.

Based on your linked code, it looks like we might be able to specify database name but not schema.

Thanks!

Comment From: wilkinsona

Yes, I think that's the case.

While not very elegant, you can make it work by post-processing the JdbcConnectionDetails bean:

@Bean
static BeanPostProcessor jdbcConnectionDetailsPostProcessor() {
    return new BeanPostProcessor() {

        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            if (!(bean instanceof JdbcConnectionDetails)) {
                return bean;
            }
            JdbcConnectionDetails jdbc = (JdbcConnectionDetails) bean;
            return new JdbcConnectionDetails() {

                @Override
                public String getUsername() {
                    return jdbc.getUsername();
                }

                @Override
                public String getPassword() {
                    return jdbc.getPassword();
                }

                @Override
                public String getJdbcUrl() {
                    return jdbc.getJdbcUrl() + "?currentSchema=application";
                }

            };
        }

    };
}

Comment From: GrantGochnauer

OK thanks. The reason we added the docker-compose addons was for convenience but I am also not a fan of adding in unnecessary code to the codebase when we had something working in our configuration file. Not sure if this could be turned into an enhancement request? Thanks!

Comment From: wilkinsona

Not sure if this could be turned into an enhancement request?

Yes, I think so. There definitely appears to be some room for improvement here.

In the meantime, you may want to label your Postgres container with org.springframework.boot.ignore: true. Spring Boot will then continue to use your spring.datasource.url property to connect to the Postgres instance running in the container while still calling docker compose up when you start your app.

Comment From: GrantGochnauer

Thank you - I will try to ignore option. I think this will work for us.

Comment From: mhalbritter

Adding a label to the service

org.springframework.boot.jdbc.parameters: currentSchema=application

should work, too. We should maybe document that.

Comment From: wilkinsona

Thanks, @mhalbritter. I'd forgotten we had that 😬. I think this is just a documentation issue now.

Comment From: GrantGochnauer

Thank you!

Adding

org.springframework.boot.jdbc.parameters: currentSchema=application

did the trick along with the environment variable: POSTGRES_DB: platform_db