0

I'm trying to learn Spring Boot (and Java) and I'm running my application and database in docker containers. The problem is when I build my containers it crashes with these kind of exceptions:

#0 13.79 2023-05-29T17:41:51.480Z  INFO 81 --- [           main] com.zaxxer.hikari.HikariDataSource       : HikariPool-1 - Starting...
#0 14.80 2023-05-29T17:41:52.481Z ERROR 81 --- [           main] com.zaxxer.hikari.pool.HikariPool        : HikariPool-1 - Exception during pool initialization.
#0 14.80
#0 14.80 org.postgresql.util.PSQLException: The connection attempt failed.

...

#0 14.80 Caused by: java.net.UnknownHostException: db

...

#0 14.80 2023-05-29T17:41:52.486Z  WARN 81 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : SQL Error: 0, SQLState: 08001
#0 14.80 2023-05-29T17:41:52.486Z ERROR 81 --- [           main] o.h.engine.jdbc.spi.SqlExceptionHelper   : The connection attempt failed.
#0 14.80 2023-05-29T17:41:52.490Z ERROR 81 --- [           main] j.LocalContainerEntityManagerFactoryBean : Failed to initialize JPA EntityManagerFactory: [PersistenceUnit: default] Unable to build Hibernate SessionFactory; nested exception is org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution [The connection attempt failed.] [n/a]

My docker-compose.yml looks like this:

services:
  backend:
    build: .
    ports:
      - 8080:8080
    environment:
      - POSTGRES_DB=example
    networks:
      - spring-postgres
    depends_on:
      - db
  db:
    image: postgres
    restart: always
    secrets:
      - db-password
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - spring-postgres
    environment:
      - POSTGRES_DB=example
      - POSTGRES_PASSWORD_FILE=/run/secrets/db-password
    expose:
      - 5432
  pgadmin:
    image: dpage/pgadmin4
    ports:
      - 5555:80
    volumes:
      - pgadmin4:/var/lib/pgadmin
    environment:
      - PGADMIN_DEFAULT_EMAIL=admin@admin.com
      - PGADMIN_DEFAULT_PASSWORD=admin
    depends_on:
      - db
    networks:
      - spring-postgres
    restart: unless-stopped
  
volumes:
  db-data:
  pgadmin4:
secrets:
  db-password:
    file: db/password.txt
networks:
  spring-postgres:

and my application.properties:

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=create
spring.jpa.hibernate.show-sql=true

spring.datasource.url=jdbc:postgresql://db:5432/${POSTGRES_DB}
spring.datasource.username=postgres
spring.datasource.password=${POSTGRES_PASSWORD:db-wrz2z}
spring.datasource.initialization-mode=always
spring.datasource.initialize=true
spring.datasource.continue-on-error=true

Here's also my pom.xml if it helps:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.nyrkes</groupId>
    <artifactId>xxx</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>xxx</name>
    <description>xxx</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                    <excludeDevtools>false</excludeDevtools>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

If I change the spring.jpa.hibernate.ddl-auto=create to none the build is successfull.

T_J
  • 1
  • 1
  • When you disable create on start - it just skips the stage where it checks if db is available. So it will build but not run properly. Your datasource url is wrong - it trys to access host with domain name db, but you don't have the one. db - is not host name, it is service name. – user453575457 May 29 '23 at 18:08
  • I solved the problem. Apparently, it had something to do with maven trying to establish a connection to the database. I changed my Dockerfile command from `RUN mvn install` to `RUN mvn install clean package -DskipTests` and it worked. This post helped me https://stackoverflow.com/a/64560678/10732109 – T_J May 29 '23 at 18:55
  • You are still just not checking connection on start, skipping tests – user453575457 May 30 '23 at 08:29

1 Answers1

0

I solved the problem. Apparently, it had something to do with maven trying to establish a connection to the database. I changed my Dockerfile command from RUN mvn install to RUN mvn install clean package -DskipTests and it worked. This post helped me stackoverflow.com/a/64560678/10732109

T_J
  • 1
  • 1
  • 1
    This answer is only a bandaid fix. You now just skip the tests but your DB URL is still wrong and the application won't run properly. – SirHawrk May 30 '23 at 06:57