[Spring] PostgreSQL docker container 세팅 및 에러 해결

WJ·2023년 7월 24일

Mr-Playlist

목록 보기
2/2


사용 이유

프로젝트가 어느정도 진척되면 docker-compose를 이용하여
redis, postgreSQL, 스프링 어플리케이션을 모두 묶어 CI/CD를 진행하기로 했기에, 로컬 DB를 이용할 수도 있지만 이 후 호환성 고려 및 docker에 조금이라도 더 친숙해지고자 docker를 이용하여 DB를 세팅하기로 결정.

세팅 전 확인

세팅 하기전 컨테이너에 바인딩할 포트를 확인해주세요..
혹시라도 저처럼 체크하지 않고 그냥 설정할 경우 충돌이 생길 수 있습니다..

윈도우의 경우 아래의 명령어를 이용하여 5432 포트가 사용중인지 확인 후 사용중이라면 호스트의 포트를 변경하여 사용하시면 됩니다.

netstat -ano | findstr 포트번호

1. 도커 이미지 받아오기

docker pull postgres:{version}

자신의 터미널을 실행 후 사용하고자 하는 버전의 postgres의 이미지를 받아옵니다.
최신 버전의 경우 docker pull postgres:latest 사용

2. 컨테이너 실행

docker run -p {호스트 포트}:{컨테이너 포트} --name {컨테이너 이름} \ // 포트 및 컨테이너 이름 설정
-e POSTGRES_PASSWORD={db password} \ // 비밀번호
-d postgres // -d 옵션을 줘서 detached 모드로 사용

컨테이너를 지워도 데이터를 계속 유지시키고자 하면 volume을 생성 후
-v pgdata:/var/lib/postgresql/data 옵션을 추가

docker volume create pgtest

아래와 같은 형태로 실행

docker run -p 5432:5432 --name postgres-container -e POSTGRES_PASSWORD=1234 -e POSTGRES_DB=testdb -d -v pgtest:/var/lib/postgresql/data postgres

docker ps 명령어를 통해 실행 되었는지 확인

3. 컨테이너 접속

아래 명령어를 사용해 접속

docker exec -it <컨테이너 이름> /bin/bash  // -it 옵션을 사용해 배시 셸을 사용
psql -U postgres // default username인 postgres로 접속

접속이 완료되었으면 DB의 접근 권한을 세팅한다.

create role testuser with login password '1234';
alter user testuser with superuser;
\l // 데이터베이스 상태 확인

grant all privileges on database testdb to testuser;

application.yml 설정

spring:
  config:
    activate:
      on-profile: local

  datasource:
    url: jdbc:postgresql://0.0.0.0:5432/testdb
    username: testuser
    password: 1234
    driver-class-name: org.postgresql.Driver
  jpa:
    database: postgresql
    database-platform: org.hibernate.dialect.PostgreSQLDialect
    hibernate:
      ddl-auto: create

    properties:
      hibernate:
        format_sql: true

테스트를 해보았는데..

에러 발생


PSQLException 에러 발생, 연결 실패.
그런데 문자열이 깨졌다?
에러 내용을 알아야 하는데, Intellij 유니코드 세팅, postgresql 컨테이너의 유니코드 세팅을 다시해도 마찬가지로 깨졌다.

팀원의 도움을 받아 열심히 구글링한 결과

org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'entityManagerFactory' 
defined in class path resource[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: [PersistenceUnit: default] 
Unable to build Hibernate SessionFactory; 
nested exception is org.hibernate.exception.GenericJDBCException: Unable to open JDBC Connection for DDL execution
치명적오류: 호스트 "내 ip", 사용자 "testuser", 데이터베이스 "testdb", 
SSL 중지 연결에 대한 설정이 pg_hba.conf 파일에 없습니다.

다음과 같은 에러였다. 이를 해결하기 위해 열심히 구글링하여 pg_hba.conf, postgresql.conf 파일도 수정해보고, 여러번 도커를 다시 세팅해보아도 해결되지 않았고
한참을 고민하고 삽질한 끝에 원인을 찾았다.

이전에 학습할때 로컬환경에서 사용했던 postgres DB가 생각이 났고,
아래의 명령어를 사용하여 확인해본 결과 5432 포트로 서비스가 계속 실행되고 있었다.

netstat -ano | findstr 5432

이때문에 계속 로컬에 존재하지않는 db와 username로 연결하려고 하니 당연히 될리가 없었고,
문자열이 깨지는 것도 결국 로컬환경의 문제였다.
실행 전 체크해야 됐었던 부분인데 이런 부분 때문에 시간을 낭비하니 너무 아까웠음..
로컬에서 postgresql이 설치된 경로에 아래 명령어를 사용해 서비스를 중지시키니 정상적으로 작동!

pg_ctl stop -mf -w -D ../data

pg_ctl에 대한 자세한 명령어는 이 곳 참조!
https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=iyagi15&logNo=10141652237

profile
주니어 개발자

1개의 댓글

comment-user-thumbnail
2023년 7월 24일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기