프로젝트를 진행하며 리모트 서버에 db를 설치해야했다. db는 도커 컨테이너를 띄우는 방식으로 진행하기로 했다.
원래 도커를 사용할 때 고려할 점이 많은 것도 알고, db는 내가 생각해도 그냥 서버 하나에 설치를 해두는게 맞다. 하지만 단순히 도커 사용에 대한 기본적인 부분을 알아보기 위해 + 서버에 각각의 것들을 설치하는 과정을 쉽게 가기 위해 DB, Nginx, api 서버 모두 컨테이너로 관리하기로 했다.
아는게 많이는 없지만 이런 문제들이 떠오른다.
이런거 다~ 무시하고 도커에 익숙해지기 위해서, 그리고 그냥 편해서 일단 썼다
기본 스펙 선정
ACG
포트 3306 열었음
공인 IP 할당
서버접속용 IP와 공인 IP는 다르다.
기본 이미지를 가지고서 컨테이너를 띄워도 충분했다. 하지만 인코딩 형식을 utf-8로 바꾸는 config 설정해야했다. 우리 데이터는 한글을 포함하니까
→ 찾아보니 cli로 해결 가능했다.
docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
--character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
→ 관리해야할 설정들을 어떻게 기억해둘까 하다가, docker-compose에 적어놓기로 했다. 원래 docker-compose는 여러 컨테이너를 한번에 관리할 때 쓰는거라 이렇게 쓰지는 않을 것 같다. docker-compose 내용은 다음과 같다.
version: "3"
services:
mysql:
image: mysql:8.0
volumes:
- mysql-volume:/var/lib/mysql
ports:
- "3306:3306"
environment:
MYSQL_ROOT_PASSWORD: 비밀번호!@#!@$!@$@!$!@#@!#
command:
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
mysql-volume:
제대로 인코딩 설정이 들어갔는지는 다음과 같이 확인 가능
SELECT default_character_set_name, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA
WHERE schema_name = "db 이름";
도커 컨테이너가 생성된 후에는 모든 작업은 컨테이너의 writable layer에서 이뤄진다. 도커 컨테이너가 죽으면, 도커 컨테이너 상에서 쓰여진 데이터들은 날아간다는 뜻이다.
그러나 mysql 설정, 데이터에 관한 부분은 설령 컨테이너가 내려가도 유지되어야한다. 따라서 이 부분은 volume으로 관리하도록 한다.
volume은 호스트의 파일 시스템을 컨테이너의 파일 시스템과 연결 시키는 방법 중 하나로, 도커가 직접 관리해준다.
위 docker-compose.yml
파일과 같이, 우분투 기준 /var/lib/mysql
부분을 volume과 연결해주면 된다.
이 때, 주의할 것이 있다. volume을 따로 설정하는 이유는 writable layer의 내용들을 잃어버리고 싶지 않아서이다. 그러나 이것도 매번 다른 volume을 사용해버린다면 어차피 무용지물이 될 것이다.
앞으로 항상 사용할 volume을 지정하고, 그 volume을 사용하도록 해야한다.
이를 위해 먼저
docker volume create mysql-volume
로, 직접 volume을 만들어주자
docker-compose.yml
에는 volumes
부분에 external
, name
속성을 추가하고, 직접 만들어준 volume의 이름을 적어줘 해당 volume을 사용하게끔 강제하자
external, name 속성이 없다면, 도커는 {docker-compose.yml이 있는 폴더 명}_mysql-volume
라는 이름의 volume을 먼저 찾고, 있으면 사용하며, 없다면 volume을 새로 만든다.
서버 acg에서 0.0.0.0에 대해 3306을 열어줘서 바로 될줄 알았는데 안됐다. db 접근 가능한 사용자를 또 따로 정의해야한다. 서버 inbound 규칙만 바꿔준다고 되는게 아니었다.
db 접근 가능한 사용자를 또 따로 정의해야한다. 서버 inbound 규칙만 바꿔준다고 되는게 아니었다. mysql 클라이언트는 mysql -h {host ip} -u {user} -p {password}
로 접속 가능하다.
리모트 서버에서 ssh로 접근한 후, 터미널에서 mysql -u root -p
로 mysql 클라이언트 접속하자. 비밀번호는 컨테이너를 띄울 때 docker-compose.yml
에서 MYSQL_ROOT_PASSWORD
로 넣어줬던 환경 변수이다.
먼저 다음을 보자
create user '사용자'@'host' identified by '비밀번호';
# ex1) 내부 접근을 허용하는 사용자 추가
create user 'test'@'localhost' identified by '0000';
# ex2) 외부 접근을 허용하는 사용자 추가
create user 'test'@'%' identified by '0000';
# ex3) 특정 ip만 접근을 허용하는 사용자 추가
create user 'test'@'123.456.789.100' identified by '0000';
# ex4) 특정 ip 대역을 허용하는 사용자 추가
create user 'test'@'192.168.%' identified by '0000';
# 모든 데이터베이스의 모든 테이블에 모든 권한을 줌
grant all privileges on *.* to '사용자'@'localhost';
# 특정 데이터베이스의 모든 테이블에 모든 권한을 줌
grant all privileges on DB이름.* to '사용자'@'localhost';
# 특정 데이터베이스의 특정 테이블에 모든 권한을 줌
grant all privileges on DB이름.테이블명 to '사용자'@'localhost';
# 특정 데이터베이스의 특정 테이블에 select 권한을 줌
grant select on DB이름.테이블명 to '사용자'@'localhost';
# 특정 데이터베이스의 특정 테이블에 select, insert 권한을 줌
grant select, insert on DB이름.테이블명 to '사용자'@'localhost';
# 특정 데이터베이스의 특정 테이블의 컬럼1과 컬럼2의 update 권한을 줌
grant update(컬럼1, 컬럼2) on DB이름.테이블명 to '사용자'@'localhost';
# 사용자 생성과 동시에 부여
grant all privileges on *.* to '사용자'@'localhost' identified by '비밀번호';
# example
grant all privileges on *.* to 'test'@'localhost' identified by '0000';
참고*
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password by 'yourpassword';
FLUSH PRIVILEGES
는 grant 테이블을 reload함으로서 변경 사항을 즉시 반영하도록 한다.결론적으로 나는 다음과 같이 진행했다.
mysql> CREATE USER 'root'@'%' IDENTIFIED BY '비밀번호';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT ALL PRIVILEGES ON buddah.* TO 'root'@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
어떤 ip이든 해당 아이디와 비밀번호를 통해 buddah 라는 테이블에 접근 가능해진다. buddah는 내 프로젝트에서 사용할 db 이름이다. 이건 미리 만들어 놓으면 될 것!
mysql - Official Image | Docker Hub
utf 설정은 conf 파일 손댈 필요 없이 cli 단에서 옵션으로 가능하다. Configuration without a cnf
file 에서 확인 가능
docker compose 쓸 때 mysql 관련 참고 사항
utf-8로 설정함
MySQL database 와 table 의 character set encoding 확인하는 법
database default encoding 확인
Docker Compose에서 각 서비스 컨테이너에 쓰이는 환경변수를 다루는 방법