서버에서 Docker로 MySQL을 세팅하면서 가장 많이 본 화면...
구글링에서도 다양한 접근 권한 해결 방법을 읽어보았지만 역시 삽질은 피할 수가 없네요.
다음은 해당 접근 권한 화면을 보지 않고 쉽게 MySQL을 세팅하기 위한 피땀 섞인 제 경험입니다.
그리고 내가 까먹지 않기 위해 메모하기.
이 화면에서 벗어나고 싶어서 다양하게 docker-compose.yml 파일을 수정해 보았지만 접속조차 불가능..
문제는 로컬에서 작업했던 것처럼 docker-compose 에서 보안 설정을 하고 시작하려고 해서 그런가..
(아니 구글링하면 다 그렇게 하던데 왜 나만 ㅜㅜ) 아무튼 다른 돌파구로 접속부터 할 수 있도록 하기로 했습니다.
docker-compose.yml
docker-compose에서는 다음과 같은 기본적인 root 세팅만 한 후 MySQL 접속 후에 보안 세팅을 시작하는게 좋습니다.
services:
mysql:
container_name: sbpb-db
image: mysql:latest
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: neonadeuli
TZ: Asia/Seoul
character-set-server: 'utf8mb4'
collation-server: 'utf8mb4_unicode_ci'
ports:
- '3306:3306'
volumes:
- ./mysql/data:/var/lib/mysql
- ./mysql/conf.d:/etc/mysql/conf.d
command:
- "mysqld"
- "--character-set-server=utf8mb4"
- "--collation-server=utf8mb4_unicode_ci"
위 세팅 코드를 보면 MYSQL 패스워드만 1234로 세팅한 것을 볼 수 있습니다. 이러면 접속은 무조건 성공!
Docker 동작 명령어
이후 다음 명령어로 Docker 명령어로 세팅된 MYSQL을 Docker에 띄우면 됩니다.
(옵션 명령어로 -d 를 붙여야 Docker가 백그라운드에서 동작한다는 거 알고 있기)
# Docker 컨테이너 올리기
docker-compose up --build -d
# Docker 컨테이너 확인
docker ps
도커가 잘 작동한다면 해당 MYSQL가 잘 동작한다는 의미입니다. 이제 접속만 잘 되기를 기도하면 됩니다.
물론 기본적인 세팅만 했기 때문에 이제 접속이 잘 될 수 밖에 없습니다!
다음은 서버 인스턴스 내부에서 Docker로 띄운 MYSQL에 접속하는 명령어 입니다.
기본 세팅으로 설정한 1234를 입력하면 곧바로 MYSQL에 접속할 수 있게 됩니다.
# 서버 내부에서 Docker로 띄운 DB 접속하기
docker exec -it sbpb-db mysql -u root -p
MySQL 권한 세팅
여기서 만약 보안 세팅없이 그대로 방치한다면 저처럼 DB 해킹을 당할 수 있습니다.
(물론 test 서버였기 때문에 리셋 후 다시 세팅할 수 있었지만 이 글을 보고 계신다면 다음 순서에 따라 꼭 보안 설정은 해두시길)
먼저 다음 명령어로 '%'가 아닌 다른 호스트에 대한 root 계정 사용 유무를 확인해주어야 합니다.
여러 개의 root 계정이 있다면 각각에 대한 비밀번호를 변경해주어야 합니다. (이 부분 중요)
# 호스트 지정 문제 확인
SELECT user, host FROM mysql.user WHERE user='root';
위 명령어에서 확인한 모든 Host의 root 계정 비밀번호를 다음 명령어 순서로 변경해주고 Docker를 재시작 해줍니다.
(-v 옵션 명령어는 Docker의 데이터 볼륨을 삭제하는 옵션이므로 어떤 옵션인지 확인 후에 추가해주세요.)
# 모든 root 비밀번호 변경
ALTER USER 'root'@'localhost' IDENTIFIED BY '새로운_복잡한_비밀번호';
ALTER USER 'root'@'%' IDENTIFIED BY '새로운_복잡한_비밀번호';
FLUSH PRIVILEGES;
# Docker 재시작
docker-compose down -v
docker-compose up -d
외부에서 서버 DB 접속하기
이제 매번 서버에 접속하여 DB에 접속하기 싫다면 외부에서 접속할 수 있도록 다음 세팅을 해주어야 합니다.
저는 'sbpb' 이라는 유저를 등록해주었습니다. 제가 사용할 유저이기 때문에 모든 호스트 접속 설정까지 해두었습니다.
# 새로운 사용자에게 localhost에서의 접속 권한 부여
CREATE USER 'sbpb'@'localhost' IDENTIFIED BY '새로운 복잡한 비밀번호';
GRANT ALL PRIVILEGES ON neonadeuli.* TO 'sbpb'@'localhost';
FLUSH PRIVILEGES;
# 모든 호스트에서의 접속 권한 부여
CREATE USER 'sbpb'@'%' IDENTIFIED BY '새로운 복잡한 비밀번호';
GRANT ALL PRIVILEGES ON neonadeuli.* TO 'sbpb'@'%';
FLUSH PRIVILEGES;
이제 로컬 환경에서 새로운 터미널을 열고 다음의 접속 명령어를 작성해줍니다.
mysql -h 서버_IP주소 -P MYSQL_포트번호 -u MYSQL_유저 -p MYSQL_비밀번호 MYSQLDB_이름
물론 이렇게 작성해주면 되지만 매번 작성하기에는 너무 길고 귀찮으니 다음의 쉘 스크립트 파일 하나 만들어주면 좋습니다.
#!/bin/bash
# 변수 정의하기
SERVER_IP="IP 주소"
MYSQL_PORT="포트번호"
MYSQL_USER="유저이름"
MYSQL_PASSWORD="복잡한 비밀번호"
MYSQL_DATABASE="DB 이름"
# MySQL database 연결하기
mysql -h $SERVER_IP -P $MYSQL_PORT -u $MYSQL_USER -p$MYSQL_PASSWORD $MYSQL_DATABASE
위 코드로 쉘 파일을 만들었다면 다음 권한 부여도 잊지 말아야 합니다.
chmod +x {쉘파일명}.sh
위 설정을 해두면 이제 아래 명령어로 쉽게 접속이 가능합니다.
./{쉘파일이름}.sh
Docker DB 초기화
그럼에도 설정 과정에서 문제가 발생하여 리셋이 필요한 경우 다음 명령어를 사용하면 좋습니다.
# Docker 컨테이너 볼륨 제거
docker-compose down -v
# Docker 컨테이너 기존 볼륨 확인
docker volume ls
# 모든 볼륨 확인 및 제거
docker volume rm <volume_name>
# 사용하지 않는 모든 볼륨 제거
docker volume prune -f
그리고 docker-compose.yml 에서 만들어진 파일을 제거하고 다음 명령어로 새롭게 생성합니다.
# 기본 mysql 데이터 디렉토리 제거
rm -rf /mysql
# Docker 컨테이너 새롭게 생성
docker-compose up --build --force-recreate -d
서버 파일 권한 보안 처리
초기 테스트 서버이긴 했지만 해킹에 대한 보안 처리가 추가적으로 필요하다고 생각했습니다.
저는 다음과 같이 서버에 있는 파일에 권한 보안 처리를 해두었고 추가적인 권한 관리도 필요하다면 해두는게 좋습니다.
# docker-compose.yml 파일과 .env 파일은 소유자만 읽고 쓸 수 있도록 설정
chmod 600 docker-compose.yml
chmod 600 .env
# mysql 디렉토리 및 내부 파일 권한 설정
chmod -R 600 mysql
chmod -R root:root mysql