Starting situation: I am building a REST-Service with Spring Boot and Maven. This REST-Service is writing to a Postgres database. Both components are dockerized and configured through the following docker-compose.yml (I use a .env file to isolate the confidential and repeated information. ${DB_Name} evaluates to "Taskitory".):

version: "0.0.1" services: db: container_name: taskitory-db image: postgres:14.1 environment: - POSTGRES_DB=${DB_NAME} - POSTGRES_USER=${DB_ADMIN_USER} - POSTGRES_PASSWORD=${DB_ADMIN_PW} - PGDATA=/data/postgres volumes: - ./postgres-volume:/data networks: - taskitory-net ports: - "60000:5432" restart: unless-stopped backend: container_name: taskitory-backend build: . networks: - taskitory-net ports: - "80:8080" depends_on: - db networks: taskitory-net: driver: bridge 

As I'm using Spring Boot with Maven and Java for my REST-Service, I use JPA and Hibernate for writing to my database. The config for accessing the db is located in the application.properties of my Spring Boot project:

server.port = 8080 logging.level.jdbc = OFF logging.level.jdbc.sqltiming = DEBUG logging.level.jdbc.resultsettable = DEBUG spring.datasource.driver-class-name = org.postgresql.Driver spring.datasource.url = jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME} spring.datasource.username = ${DB_CLIENT_USER} spring.datasource.password = ${DB_CLIENT_PW} spring.datasource.hikari.max-lifetime = 600000 spring.datasource.testWhileIdle = true spring.datasource.test-on-borrow = true spring.datasource.hikari.schema = backend spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect spring.jpa.hibernate.ddl-auto = validate 

I use the variables from the .env file in the application.properties too. Therefore the spring.datasource.url evaluates from "jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME}" to "jdbc:postgresql://db:5432/Taskitory" with the following code from the .env file:

DB_ADDR_ALIAS="db" DB_PORT="5432" DB_NAME="Taskitory" DB_BE_SCHEMA="backend" 

Problem description: For my Spring Boot application to connect to the database I set the host of the jdbc-url to the service name of my DB container ("db") specified in my docker-compose.yml. Also I set the port of the jdbc-url to the native port of postgres "5432". This way the DB container should be accessible from the Spring Boot container through the docker-network "taskitory-net" which both containers are connected to. When I try to build my Spring Boot Application the following error appears (I needed to shorten the error messages to not blow the character limit):

#10 30.45 Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME} #10 30.45 at com.zaxxer.hikari.util.DriverDataSource.<init>(DriverDataSource.java:110) ~[HikariCP-4.0.3.jar:na] #10 30.45 at com.zaxxer.hikari.pool.PoolBase.initializeDataSource(PoolBase.java:331) ~[HikariCP-4.0.3.jar:na] #10 30.45 at com.zaxxer.hikari.pool.PoolBase.<init>(PoolBase.java:114) ~[HikariCP-4.0.3.jar:na] #10 30.45 at com.zaxxer.hikari.pool.HikariPool.<init>(HikariPool.java:108) ~[HikariCP-4.0.3.jar:na] #10 30.45 at com.zaxxer.hikari.HikariDataSource.getConnection(HikariDataSource.java:112) ~[HikariCP-4.0.3.jar:na] #10 30.45 at org.hibernate.engine.jdbc.connections.internal.DatasourceConnectionProviderImpl.getConnection(DatasourceConnectionProviderImpl.java:122) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.engine.jdbc.env.internal.JdbcEnvironmentInitiator$ConnectionProviderJdbcConnectionAccess.obtainConnection(JdbcEnvironmentInitiator.java:181) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.resource.transaction.backend.jdbc.internal.DdlTransactionIsolatorNonJtaImpl.getIsolatedConnection(DdlTransactionIsolatorNonJtaImpl.java:44) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.internal.exec.ImprovedExtractionContextImpl.getJdbcConnection(ImprovedExtractionContextImpl.java:63) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.extract.spi.ExtractionContext.getQueryResults(ExtractionContext.java:43) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.extract.internal.SequenceInformationExtractorLegacyImpl.extractMetadata(SequenceInformationExtractorLegacyImpl.java:39) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.initializeSequences(DatabaseInformationImpl.java:66) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.extract.internal.DatabaseInformationImpl.<init>(DatabaseInformationImpl.java:60) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.internal.Helper.buildDatabaseInformation(Helper.java:183) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.internal.AbstractSchemaValidator.doValidation(AbstractSchemaValidator.java:68) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.performDatabaseAction(SchemaManagementToolCoordinator.java:200) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator.process(SchemaManagementToolCoordinator.java:81) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:335) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:471) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1498) ~[hibernate-core-5.6.3.Final.jar:5.6.3.Final] #10 30.45 at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:58) ~[spring-orm-5.3.14.jar:5.3.14] #10 30.45 at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365) ~[spring-orm-5.3.14.jar:5.3.14] #10 30.45 at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[spring-orm-5.3.14.jar:5.3.14] #10 30.45 ... 86 common frames omitted #10 30.45 #10 30.48 [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 3.495 s <<< FAILURE! - in de.krayadev.taskitory.TaskitoryApplicationTests #10 30.49 [ERROR] contextLoads Time elapsed: 0.007 s <<< ERROR! #10 30.49 java.lang.IllegalStateException: Failed to load ApplicationContext #10 30.49 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME} #10 30.49 Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME} #10 30.49 Caused by: java.lang.RuntimeException: Driver org.postgresql.Driver claims to not accept jdbcUrl, jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME} 

What I tried:

  1. I tried to build the Spring Boot application with the DB container up and running and with it stopped. In both cases this error comes up.
  2. I tried all combinations of host ("db", "localhost", ".env-variable") and port ("5432", "60000", ".env-variable") for the jdbc-url.
  • With using the .env-variables I get the above shown error.
  • In case of using the host "db" (not over .env-variable) with any port I get the following error:
#10 28.84 Caused by: java.net.UnknownHostException: db #10 28.84 at (NioSocketImpl.java:567) ~[na:na] #10 28.84 at (SocksSocketImpl.java:327) ~[na:na] #10 28.84 at (Socket.java:633) ~[na:na] #10 28.84 at org.postgresql.core.PGStream.createSocket(PGStream.java:231) ~[postgresql-42.2.18.jar:42.2.18] #10 28.84 at org.postgresql.core.PGStream.<init>(PGStream.java:95) ~[postgresql-42.2.18.jar:42.2.18] #10 28.84 at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98) ~[postgresql-42.2.18.jar:42.2.18] #10 28.84 at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213) ~[postgresql-42.2.18.jar:42.2.18] #10 28.84 ... 115 common frames omitted #10 28.84 #10 28.87 [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 4.365 s <<< FAILURE! - in de.krayadev.taskitory.TaskitoryApplicationTests #10 28.87 [ERROR] contextLoads Time elapsed: 0.005 s <<< ERROR! #10 28.87 java.lang.IllegalStateException: Failed to load ApplicationContext #10 28.87 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution #10 28.87 Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution #10 28.87 Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution #10 28.87 Caused by: org.postgresql.util.PSQLException: The connection attempt failed. #10 28.87 Caused by: java.net.UnknownHostException: db 
  • With the host "localhost" and any port I get the following error:
#10 29.47 Caused by: java.net.ConnectException: Connection refused #10 29.47 at (Native Method) ~[na:na] #10 29.47 at (Net.java:672) ~[na:na] #10 29.47 at (NioSocketImpl.java:542) ~[na:na] #10 29.47 at (NioSocketImpl.java:597) ~[na:na] #10 29.47 at (SocksSocketImpl.java:327) ~[na:na] #10 29.47 at (Socket.java:633) ~[na:na] #10 29.47 at org.postgresql.core.PGStream.createSocket(PGStream.java:231) ~[postgresql-42.2.18.jar:42.2.18] #10 29.47 at org.postgresql.core.PGStream.<init>(PGStream.java:95) ~[postgresql-42.2.18.jar:42.2.18] #10 29.47 at org.postgresql.core.v3.ConnectionFactoryImpl.tryConnect(ConnectionFactoryImpl.java:98) ~[postgresql-42.2.18.jar:42.2.18] #10 29.47 at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:213) ~[postgresql-42.2.18.jar:42.2.18] #10 29.47 ... 115 common frames omitted #10 29.47 #10 29.49 [ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 5.539 s <<< FAILURE! - in de.krayadev.taskitory.TaskitoryApplicationTests #10 29.49 [ERROR] contextLoads Time elapsed: 0.005 s <<< ERROR! #10 29.49 java.lang.IllegalStateException: Failed to load ApplicationContext #10 29.49 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution #10 29.49 Caused by: javax.persistence.PersistenceException: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution #10 29.49 Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution #10 29.49 Caused by: org.postgresql.util.PSQLException: Connection to localhost:60000 refused. Check that the hostname and port are correct and that the postmaster is accepting TCP/IP connections. #10 29.49 Caused by: java.net.ConnectException: Connection refused 

If you miss something for solving my problem feel free to comment.

3 Answers

You should be passing the .env variables to backend container as you did for db:

 backend: environment: DB_ADDR_ALIAS: '${DB_ADDR_ALIAS}' DB_PORT: '${DB_PORT}' 

For the name resolution part, I would give a try for "taskitory-db".

4

I think I solved the part with the .env-variables in the application.properties file. To do this, I defined environment variables for the build time in the Dockerfile of my Spring Boot application using the ARG command. I initialized these args in Docker-compose.yml with the .env variables:

Dockerfile

FROM maven:3.8.4-openjdk-17-slim AS build ARG DB_ADDR_ALIAS ARG DB_PORT ARG DB_NAME ARG DB_CLIENT_USER ARG DB_CLIENT_PW 

Docker-compose.yml

backend: container_name: taskitory-backend build: context: . args: - DB_ADDR_ALIAS=${DB_ADDR_ALIAS} - DB_PORT=${DB_PORT} - DB_NAME=${DB_NAME} - DB_CLIENT_USER=${DB_CLIENT_USER} - DB_CLIENT_PW=${DB_CLIENT_PW} 

.env file

DB_ADDR_ALIAS=db DB_PORT=5432 DB_NAME=Taskitory DB_CLIENT_USER=client DB_CLIENT_PW=********* 

application.properties

spring.datasource.url = jdbc:postgresql://${DB_ADDR_ALIAS}:${DB_PORT}/${DB_NAME} spring.datasource.username = ${DB_CLIENT_USER} spring.datasource.password = ${DB_CLIENT_PW} 

However, there is still the problem that the Spring Boot application does not recognize the host "db" at build time: Caused by: java.net.UnknownHostException: db . During my research I came to the conclusion that in the "application.properties" file only the combination "jdbc:postgresql://db:5432/Taskitory" for the field "spring.datasource.url" is applicable. The use of localhost inside of the backend container would reference the backend container itself and therefore is not applicable for connecting to the db container.

I solved the issue by adding -DskipTests=true to my mvn package in the DOCKERFILE:

FROM maven:3.8.4-openjdk-17-slim AS build ARG DATABASE_ADDR_ALIAS ARG DATABASE_PORT ARG DATABASE_NAME ARG DATABASE_CLIENT_USER ARG DATABASE_CLIENT_PW COPY src /Taskitory/src COPY pom.xml /Taskitory RUN mvn -f /Taskitory/pom.xml clean package -DskipTests=true 

The problem was that the Spring Boot application of course couldn't find the docker network in build time. Therefore the application couldn't be run to run the tests.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.