이번에 백엔드 서버를 구축하면서 Web Server - Web Application Server - DB 와 같은 구조로 구축하게 되었다.
우선, 처음에 페어인 제이온과 함께 배포를 진행할 때에는 한 인스턴스에서 모든 것을 구성해 진행했다.
즉, 한 서버에서 먼저 애플리케이션 서버를 배포한 뒤, nginx를 이용하여 Proxy를 관리하고, mysql 서버를 이용하여 내부 localhost로 db를 연결하였다.
하지만 이 모든 과정 중 디비와 서버 인스턴스를 분리하는 것이 맞다고 판단하였고, 분리하는 과정을 글로 남겨보려 한다.
따라서 이 글은 한 인스턴스에 Web Server(Https로 바인딩해주는 Reverse Proxy) <-> Web Application Server <-> Database가 배포되어있다는 가정 하에, 데이터베이스를 떼어 내 볼 것이다.
Database용 인스턴스 분리하기
별도의 EC2(ubuntu 18.04 LTS)를 생성한 뒤, mysql-server를 설치한다. 그리고 MySQL에서 이용할 계정을 생성하면서 동시에 WAS의 Private IP에 대해 모든 권한을 부여한다.
Mysql 기본 설정하기
$ sudo apt update
$ sudo apt install mysql-server
$ sudo mysql -uroot -p
# create user {MySQL 유저명}@'{WAS Server Private IP}' identified by '{MySQL 유저 password}';
# CREATE DATABASE {schema} DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
# grant all privileges on {schema}.* to {MySQL 유저명}@'{WAS Server Private IP}';
# flush privileges;
만약 도커를 설치해서 mysql을 실행하는 경우에는 다음과 같이 할 수 있다.
1. docker-compose.yml 파일을 만든 뒤 다음을 작성한다.
version: '3'
services:
local-db:
image: library/mysql:5.7
container_name: {사용할 컨테이너 명}
restart: always
ports:
- 13306:3306
environment:
MYSQL_ROOT_PASSWORD: {mysql root 사용자에게 설정할 비밀번호}
TZ: Asia/Seoul
volumes:
- ./db/mysql/data:/var/lib/mysql
- ./db/mysql/init:/docker-entrypoint-initdb.d
2. docker 명령어로 서버를 실행한다.
이 때, 앞선 docker-compose.yml 파일이 위치한 경로에서 아래 //도커 실행하기 명렁어를 수행한다.
//도커 실행하기
docker-compose up -d
//도커 정지하기
docker stop $(docker container ls -q)
// 도커 삭제하기
docker-compose rm -v -f
sudo rm -rf db
3. mysql을 실행한다.
docker exec -it {container name} bash
4. 위의 mysql 기본 설정하기 과정을 수행한다.
다음으로, mysql 설정 파일을 열어, 보안그룹에 허용되어있는 포트를 port로 설정한다.
그리고 bind-address로 WAS 서버의 private IP를 등록한다. 0.0.0.0을 등록한다.
이 부분에 대해서는 접은글로 작성하겠다.
bind-address에 WAS의 private IP를 등록하면 mysql server를 restart할 때 에러가 발생한다.
그 이유를 확인해보기 위해 Mysql error log를 확인해보니, 다음과 같이 나왔다.
이는 WAS와 디비가 동일한 보안그룹을 이용하고 있기 때문에 우리는 디비의 포트도 8080으로 뚫어주어야했는데, 이 때 WAS의 private-ip를 bind-address로 작성하면 이미 WAS의 private IP의 8080 포트에는 바인딩된 것이 존재하기 때문에 예외가 발생하는 것이었다. 🤭
$ sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf
-- 보안 그룹에 허용되어있는 포트로 설정
port = 8080 [보안 그룹에 맞는 포트번호]
bind-address = 0.0.0.0
--
-- 설정을 모두 완료한 뒤 mysql을 재시작한다.
$ sudo service mysql restart
이제, 애플리케이션 서버의 yml 또는 properties 파일에 우리의 데이터베이스 인스턴스 아이피를 연결한다.
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://{DB 인스턴스 private IP}:{mysqlconf.d에 설정한 Port}/{schema}?serverTimezone=UTC&characterEncoding=UTF-8
username: {MySQL 계정}
password: {MySQL 계정 비밀번호}
handlebars:
suffix: .html
enabled: true
security:
jwt:
token:
secret-key: my_secret_is_secret
expire-length: 3600000
mysql.cnf 파일의 bind-address를 db 인스턴스의 private ip로 설정해도 연결이 허용되는데 그 이유에 대해서는 https://joanne.tistory.com/178 이 글에서 자세히 다루겠다.