0

I'm currently learning docker and how I can dockerize my REST API but I'm having problems connecting my api image with api written in Spring and my Postgres database image from Docker Hub. I have watched multiple examples but I just cannot figure what I'm doing wrong. This is my docker-compose file:

version: '3.9'
services:
  restapi:
    container_name: stats-api
    image: 'statistics-api'
    build: .
    networks:
      - api-postgres
    ports:
      - "7000:9000"
    depends_on:
      - postgres
    restart: unless-stopped
    volumes:
      - ./target/statistics-api.jar:/statistics-api.jar
  postgres:
    container_name: postgres
    image: postgres
    networks:
      - api-postgres
    ports:
      - "5332:5432"
    environment:
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: admin123#
      POSTGRES_DB: statistics
      PGDATA: /data/postgres
    volumes:
      - postgres-data:/data/postgres
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 10s
      timeout: 5s
      retries: 5
    restart: unless-stopped
volumes:
  postgres-data:
networks:
  api-postgres:

This is my Dockerfile:

FROM openjdk:17
ADD target/statistics-api.jar statistics-api.jar
ENTRYPOINT ["java", "-jar", "statistics-api.jar"]

This is my application.yml file:

server:
  port: 9000

spring:
  datasource:
    password: admin123#
    username: admin
    url: jdbc:postgresql://localhost:5332/statistics
  jpa:
    hibernate:
      ddl-auto: create-drop
    properties:
      hibernate:
        dialect: org.hibernate.dialect.PostgreSQLDialect
        format_sql: true
    show_sql: true
  main:
    web-application-type: servlet

This is the error I get after running docker-compose up:

Also one note I'm using Docker on Windows that uses WSL version 2.

Dusan Bjelica
  • 23
  • 1
  • 6

1 Answers1

2

Every docker container is it's own machine, therefore, the IP is different. In your case, rather than using localhost, you have to specify the hostname of the postgres container and use that hostname in your application.yml instead.

When using localhost in your container, you're not referring to the host but rather the container itself, and most commonly, you won't have the database running in the same container as your consumer.

What you're doing is trying to break out of the container and then connecting to another container that is already in the network of the first one. That's a bad practice and unnecessary.
If you do want to actually use the host (which should pretty much only be if you access something that isn't in a container), follow this SO answer

SIMULATAN
  • 833
  • 2
  • 17
  • Thank you, this has helped me but now I get error which says that connection to the postgres is refused. – Dusan Bjelica Mar 17 '23 at 16:17
  • Keep in mind that you have to use the port **in the container**, not the **published** port, so in your case, that would be `5432`. Additionally, make sure that the hostname matches and you set it manually on the `postgres` service. – SIMULATAN Mar 17 '23 at 18:06