server | Error: P1001: Can't reach database server at `mysql`:`3306`
server |
server | Please make sure your database server is running at `mysql`:`3306`.
server 컨테이너에서 mysql 데이터베이스에 접속이 안 된다. 데이터베이스 url도 컨테이너명으로 제대로 설정도 했고, 같은 네트워크로 연결까지 해줬는데 안 되는 이유가 뭔지 한참을 찾았다.
DATABASE_URL=mysql://root:passowrd@mysql:3306/database?connect_timeout=300
version: '3'
services:
db:
image: mysql:8.0.31
container_name: mysql
restart: always
env_file:
- ./db/.env
volumes:
- ./db/data:/var/lib/mysql
networks:
- chat-network
ports:
- 3306:3306
server:
build:
context: ./server
dockerfile: Dockerfile
container_name: server
depends_on:
- db
networks:
- chat-network
ports:
- 8080:8080
env_file:
- ./server/.env
- ./server/.env.development
networks:
chat-network:
driver: bridge
💡 알고보니 데이터베이스보다 server가 먼저 실행되서 발생하는 문제였다. 그래서 dockerize를 사용하여 데이터베이스가 실행되기 전에 server의 시작을 지연시켜서 해결했다. dockerize에 대한 사용법은 dockerize github에서 볼 수 있다.
Dockerfile
에는 dockerize 다운로드 명령어를 추가하고 docker-entrypoint.sh
에는 mysql을 기다리는 명령어를 추가했다.
# Dockerfile
ENV DOCKERIZE_VERSION v0.6.1
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& tar -C /usr/local/bin -xzvf dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
&& rm dockerize-linux-amd64-$DOCKERIZE_VERSION.tar.gz
# docker-entrypoint.hs
echo "waiting for a database to be ready"
dockerize -wait tcp://mysql:3306 -timeout 20s
server | Error: P1000: Authentication failed against database server at `mysql`, the provided database credentials for `root` are not valid.
server |
server | Please make sure to provide valid database credentials for the database server at `mysql`.
docker inspect 명령어로 prisma 데이터베이스 url과 데이터베이스 컨테이너의 env를 확인했는데 정상적으로 입력되어 있었다.
그러나 doker exec -it mysql bash
명령어를 통해 mysql에 접속하니 또 동일하게 비밀번호 오류가 났다. mysql 컨테이너를 여러번 생성했었는데 이전에 쓰던 비밀번호를 입력하니 이번에는 제대로 작동했다.
💡 결과적으로 문제는 볼륨에 있었다. 기존에 사용하던 볼륨이 남아있어서 이전의 비밀번호 환경변수가 사용되고 있었다. docker volume ls
명령어로 필요하지 않은 볼륨을 삭제해 주고 바인드 마인트로 연결되어 있던 /db/data를 비워줬더니 해결되었다.