1

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    
7
  • 1
    Do you have a log from postgres container? Did it start properly? Commented Dec 11, 2021 at 15:45
  • that's actually a good question... it seems that it's not even started by the docker-compose command for some reason. Commented Dec 11, 2021 at 15:49
  • Can you remove -q from RUN command in your Dockerfile? It may be hiding an error. Commented Dec 11, 2021 at 16:02
  • I added it because it was flooding my logs and they would reach the limit, concealing the actual errors related to the impossibility of connecting to the database. : #8 44.19 [output clipped, log limit 1MiB reached] Commented Dec 11, 2021 at 16:04
  • Try changing spring.datasource.url=jdbc:postgresql://postgres:5432/nanobox to spring.datasource.url=jdbc:postgresql://db:5432/nanobox. Your docker compose has postgres's container name as db where as in application.properties is not pointing to this container name Commented Dec 11, 2021 at 17:08

3 Answers 3

0

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
Sign up to request clarification or add additional context in comments.

5 Comments

RUN mvn clean install -q results in the same error.. CMD is never reached. it seems that the postgres container does not start in the background for some reason.
Just compiling your application shouldn't require a database running, no?
I am honestly not getting your point, it might be the case that I'm still a beginner when it comes to theoretical knowledge about Spring and Docker. What I tried to say is that even with your changes, it does not work. Hostname is not resolved because postgres container is not up.
What is mvn install doing that it needs to connect to a database at all?
I do not know! The only thing that I know is that it fails, so my problem is not solved.
0

@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.

Comments

0

First, inspect your Postgres container using the command docker inspect pg. pg is my Postgres container name. Check the network section. Ref the picture I have attached. docker_inpect_pg_output. My Postgres docker container IP address is 172.17.0.2. And I replaced my old code with dataSource.setUrl("jdbc:postgresql://172.17.0.2:5432/databasename");

1 Comment

this problem was solved. Check accepted answer below (my own answer). Putting a hardcoded IP for the postgres docker container would be a bad idea, anway (and it was not the problem, the problem was that maven tried doing some DB related tests before the db was up).

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.