skip to Main Content

I am trying to containerise a Spring Boot project that uses another containerised Postgres database, but it seems the Spring project cannot connect to the database because it cannot resolve the hostname.

Dockerfile:

FROM maven:3.6.0-jdk-11
WORKDIR /app
COPY . /app
RUN mvn clean install spring-boot:run -q

Docker compose:

version: "3.7"

services:
  postgres:
    image: postgres
    container_name: db
    expose:
      - "5432"
    ports:
      - "5432:5432"
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: nanobox
    networks:
      - app-network
  
  backend:
    restart: always
    build:
      context: nanobox
    volumes:
      - ./nanobox:/app
    environment:
      - SECRET=bigsecret
    ports:
      - 8081:8081
    networks:
      - app-network
    depends_on:
      - postgres


networks:
  app-network:
    driver: bridge

application.properties:

logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
#debug=false

spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://postgres:5432/nanobox
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.generate-ddl=true
spring.jpa.database=postgresql
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.properties.hibernate.jdbc.lob.not_contextual_creation=true
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
debug=true
spring.mvc.log-request-details=true
auth.secret={SECRET}
storage.prefix = /tmp/uploads/

docker compose up fails with the following exceptions:

#8 44.67 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
    [..]
#8 44.67 Caused by: org.hibernate.exception.JDBCConnectionException: Unable to open JDBC Connection for DDL execution
    [..]
#8 44.68 Caused by: org.postgresql.util.PSQLException: The connection attempt failed.
    [..]
#8 44.68 Caused by: java.net.UnknownHostException: postgres

It seems that for some reason docker compose refuses to start the postgres container before the Spring application, even the command:

docker compose up postgres backend

results in:

[+] Building 8.3s (8/8) FINISHED                                                                                                                                                                                                                                                                                            
 => [internal] load build definition from Dockerfile                                                                                                                                                                                                                                                                   0.0s
 => => transferring dockerfile: 31B                                                                                                                                                                                                                                                                                    0.0s
 => [internal] load .dockerignore                                                                                                                                                                                                                                                                                      0.0s
 => => transferring context: 2B                                                                                                                                                                                                                                                                                        0.0s
 => [internal] load metadata for docker.io/library/maven:3.6.0-jdk-11                                                                                                                                                                                                                                                  1.5s
 => [1/4] FROM docker.io/library/maven:3.6.0-jdk-11@sha256:6a0430ded2cfaba7e16080f4cc097c9c65d1406b3b235d0fcfcfd84c354c4177                                                                                                                                                                                            0.0s
 => [internal] load build context                                                                                                                                                                                                                                                                                      0.0s
 => => transferring context: 18.55kB                                                                                                                                                                                                                                                                                   0.0s
 => CACHED [2/4] WORKDIR /app                                                                                                                                                                                                                                                                                          0.0s
 => CACHED [3/4] COPY . /app    

2

Answers


  1. Chosen as BEST ANSWER

    @david-maze 's solution was almost good for my case. However, I solved the problem with this following Dockerfile:

    FROM maven:3.6.0-jdk-11
    WORKDIR /app
    COPY . .
    
    # At build time, only compile the application but do not run it
    RUN mvn clean package -DskipTests -q
    
    # When you launch the container, this will be the main command
    CMD mvn spring-boot:run
    

    also had to add an alias for the database container:

    postgres:
        image: postgres
        container_name: db
        expose:
          - "5432"
        ports:
          - "5432:5432"
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: nanobox
          networks:
            some-net:
              aliases:
                - auth-module.dev
    

    Maven was running tests that resulted in container launch failure because there was no database.


  2. You’re trying to run mvn spring-boot:run from a Dockerfile RUN instruction; that happens while you’re trying to build the image, not when you go to run the container later. (It’s similar to the difference between using javac to compile a source file and java to run the built class file.) For reasons beyond the scope of this answer, the build phase can’t connect to other containers, even if they’re declared in the same docker-compose.yml file.

    Split the Dockerfile into two separate lines to build the application, and then to run it as the main container command:

    FROM maven:3.6.0-jdk-11
    WORKDIR /app
    COPY . .      # (don't repeat /app directory name)
    
    # At build time, only compile the application but do not run it
    RUN mvn clean install
    
    # When you launch the container, this will be the main command
    CMD mvn spring-boot:run
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search