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