발생한 문제
로컬 환경(Windows)에 이미 MySQL이 설치되어 있었고, 기본 포트인 3306에서 실행 중이었다. 추가적으로 Docker 컨테이너를 통해 또 다른 MySQL을 설치하고자 했는데, Docker에서 실행할 때도 기본 포트(3306)를 사용하여 충돌이 발생했다. 이로 인해 Docker 컨테이너의 MySQL이 정상적으로 실행되지 않았고, Spring Boot 애플리케이션이 MySQL 데이터베이스에 연결할 수 없는 문제가 발생하였다.

해당 에러는 데이터베이스 연결 설정이 잘못되었거나 연결할 수 없어서 Hibernate가 연결 메타데이터를 얻어오는 과정에서 NullPointerException이 발생한 것
이다.
- 데이터베이스 연결 정보 오류
- DB 계정 권한 설정
- mysql 컨테이너 실행 상태
- mysql 외부 접속 설정
데이터베이스 연결이 되지 않은 이유를 해결해야 했고 연결되지 않은 이유는 다음과 같이 다양해서 하나씩 점검하며 해결해 보았다.
발생한 오류
Docker로 MySQL 컨테이너를 실행했을 때 다음과 같은 명령어를 사용했다
bashdocker run --name mark-board-mysql -e MYSQL_ROOT_PASSWORD=root -p 3306:3306 -d mysql:8.0.38
Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3306 -> 0.0.0.0:0: listen tcp 0.0.0.0:3306: bind: Only one usage of each socket address (protocol/networ
k address/port) is normally permitted.
이 경우 3306 포트는 이미 사용 중이라 정상적으로 생성되지 못하고 에러가 발생했다.

netstat -ano | findstr :3306
명령어로 어떤 프로세스가 3306 포트를 사용중인지 확인해보니 PID 26448이 사용중이었다.
1. 포트 번호 3307로 변경하고 3306으로 포워딩하기
찾아보니 해결하는 두 가지 방법이 있었는데 먼저 3306 port를 kill하고 도커가 사용하는 방식이었다. 하지만 local의 mysql은 그대로 사용하기 위해 두 번째 방법인 도커의 mysql을 3307 포트로 사용하는 방식을 선택했다.
docker run --name mark-board-mysql -e MYSQL_ROOT_PASSWORD=root -p 3307:3306 -d mysql:8.0.38
다음과 같이 로컬 MySQL과 충돌하지 않도록 Docker 컨테이너의 포트를 3307로 변경했다. Docker 내부의 MySQL은 기본 포트 3306을 유지하면서, 호스트 시스템에서는 3307 포트로 접근하도록 설정한 것이다. 즉 외부에서 3307 포트로 접속하면 docker 내에서는 3306 포트로 포워딩하는 방식
이다.
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3307/mark_board
username: root
password: ****
driver-class-name: com.mysql.cj.jdbc.Driver
데이터베이스 연결 설정도 다시 3306 -> 3307 포트로 수정하였다.

docker ps로 실행중인 컨테이너를 확인하였고 3307->3306 으로 잘 포워딩 되는 것을 확인할 수 있다. 또한 3307 포트도 열려있다. 다시 실행해보니 여전히 같은 문제가 발생했다.
2. DB 계정 권한 설정
로컬 Spring 서버에서 Docker Container의 mysql에 접근하기 때문에 root@localhost
가 아닌 root@%
(외부 접속) 계정을 생성해야 하나?
CREATE USER 'root'@'%' IDENTIFIED BY 'root';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
혹시나 해서 도커 mysql 내부에서 계정을 생성해주고 권한도 부여해 주었다. 역시나 안된된다.
3. mysql 외부 접속 설정
그럼 mysql에서 외부 접속 설정을 막아 놓은 것은 아닐까? mysql 서버가 어떤 IP에서의 접속을 허용할지 지정하는 설정인 bind-address
를 확인하였다.
cat /etc/mysql/my.cnf | grep bind-address
설정을 해주지 않으면 default 값은 bind-address = 0.0.0.0
이며 외부 모든 IP에서 접속 가능하다. 임의로 지정을 해주지 않은 상태여서 default 값이 적용되긴 하지만 혹시나 해서 bind-address = 0.0.0.0
를 명시해주었다. 여전히 같은 문제가 발생한다.
4. window 검생창에서 service 검색 -> mysql -> 중지 -> 시작
위 과정을 8시간 넘게 반복하다 해결하지 못하였고 우연히 한 블로그를 봤다. https://donotknowwhat.tistory.com/105

window 검생창에서 service 검색 -> mysql -> 중지 -> 시작
mysql을 완전히 종료하고 다시 실행하였다. 3307 포트를 제대로 열었다고 생각했는데 처음에 도커 mysql에서 3306 포트를 사용하려고 하다 문제가 발생한 것 같다. 돌고 돌아 왔지만 간단한 방법으로 해결을 하였다.