리그캣의 개발놀이터

spring 프로젝트내에서 docker를 사용하여 mysql dockerfile, docker-compose 구성하기 본문

개발 공부/SpringFramework

spring 프로젝트내에서 docker를 사용하여 mysql dockerfile, docker-compose 구성하기

리그캣 2021. 1. 3. 15:42

Spring project를 하면서 개인적 또는 소수에 인원이 db server를 구성하고, 접근하는 것은 비용적으로나, 시간적으로나 복잡한 작업이라 생각이 들었다.

 

localhost내에서 mysql을 구성하면 외부 접근에 문제도 없을 것이고 

어차피 스터디 용으로 구성한 test db를 github에 공유하는 것 자체가 (테스트 소스코드 한정) 보안상의 이슈도 없을 것이라 생각하기 때문이다. 물론, github에 db volume을 올리게 되면 용량을 커질 것이지만  테이블 몇개정도야 뭐... 라고 생각하여 spring boot안에 mysql 코드를 구성하여보았다. (물론, 나의 생각이 잘못되었을 수 있다)

 

 

먼저 구성한 구성도이다. 

Spring boot project안에 mysql 구조만 살펴보기 바란다.


디렉토리 구조를 하나하나 살펴보겠다.


conf : conf는 컨테이너안의 mysql.conf 와 볼륨 연동시켜줄 부분이다.

data : mysql의 db 데이터와 연동할 부분이다. 컨테이너는 항상 장애가 날것을 대비하여 구성하는 것이고, 그에 따라 db볼륨을 호스트와 마운드 해주었다.

init : create.sql 안에 초반 db구성시 create문을 공유해두었다. 이는 타 개발자가 어떤 schema를 만들었는지 공유할 수 있을 정도만, 마운트는 안할것이다. 왜냐면.. 어차피 data directory를 github에 올릴것이고 다른 개발자가 github에서 해당 directory를 공유받기에 이미 schema는 구성되어있을 상태이기 때문이다. 

Dockerfile : mysql 이미지를 구성하기위한 dockerfile이다.

docker-compose.yml : container를 구성하기 위한 docker-compose 문으로 docker run 명령어보다. docker-compose 문을 쓰기를 지향한다. 이유는 히스토리성으로 갖고있을 필요가있기 때문이다.

 

만약 A 개발자가 docker run 명령어를 공유하지 않으면 B개발자는 docker run 명령어의 어떤 옵션을 실행할지 모른다. 도커는 항상 삭제되는것을 염두해두고 구현해야한다.

 

README.md : 그냥 간단히 이미지 빌드, 컨테이너 구동, 삭제에 대해서 명시해둔다. 

 

README.md 예시

 

자 이제 Dockerfile을 구성해보자.

 

```Dockerfile

# ref - https://kamang-it.tistory.com/entry/DockerMysqlInitSql

FROM mysql:5.7
MAINTAINER league3236 <league3236@gmail.com>

#ADD ./init /docker-entrypoint-initdb.d
EXPOSE 3306
CMD ["mysqld"]

```

 

#ADD ./init /docker-entrypoint-initdb.d 을 주석처리한것을 data 볼륨자체를 repository에 올리고 공유하고 쓸거니깐. (물론, 보안적에는 치명적이지만. .. )

 

이제 해당 dockerfile을 가지고 빌드를 하여 image를 만들어보자



```/bin/bash

$ docker build -t leaguemysql:1.0 .

```

위의 명령어에 대한 설명은 아래와 같다.

$ docker build -t {이미지이름}:{이미지태그} {dockerfile이 있는 path}


구성한 이미지가 잘완성되었으면 다음과 같이 조회할 수 있다.

name leaguemysql tag 1.0 으로 구성된 이미지가 생성되었다.

구성된 이미지를 docker run으로 실행할 수 있겠지만 히스토리를 위해 docker-compose를 작성하였다.


docker-compose.yml은 아래와 같이 구성하였다.

```yaml

version: '3.3'
services:
  db:
    image: leaguemysql:1.0
    volumes:
      - ./data:/var/lib/mysql
      - ./conf:/etc/mysql/conf.d
      # - ./mysql-init-files/:/docker-entrypoint-initdb.d/
    restart: always
    container_name: leaguemysql
    environment:
      - MYSQL_ROOT_PASSWORD="1234"
    ports:
      - '3333:3306'
    expose:
      - '3333'

```

이때 볼륨을 봐보자.  호스트 ./data에 데이터를 저장시키고, ./conf를 통하여 mysql.conf를 공유하게 해놓았다.

restart : always를 통해 컨테이너가 중지되어도 재시작하게 설정하였다.

MYSQL_ROOT_PASSWORD 환경변수를 통해 root 비밀번호를 1234로 설정하였다.

호스트 포트 3333과 컨테이너 포트 3306을 매핑하여 추후 mysql를 3333으로 접근할 수 있다.

 

docker-compose를 구동시키는 명령어는 해당 mysql directory에서 아래의 명령어를 치면된다.

```/bin/bash

$ docker-compose up -d

```

 

자 이제 구성한 mysql container에 접근해보자

 

docker ps -a 명령어로 구성한 컨테이너를 볼 수 있다.

docker exec 명령어로 컨테이너 안에 진입해보자. 

mysql 진입을 해보자

 

해당 명령어를 통하여 root를 통하여 접근가능한 ip 목록을 볼 수 있다. 이때 %로 지정되어있으면 외부 접속이 가능하다는 뜻이다.

 

./data로 볼륨 구성을 해두었으므로 나같은 경우엔 이전에 만들어진 table을 확인할 수 있었다.

이전에 만들어 둔 study schema

해당 블로그를 보시는 분들은 study라는 schema가 없을 것이다. 

 

나는 table도 만들어 놓았기에 git repo에서 당겨온 소스코드로 서로 공유가 가능하다.

 

이제 Mysql 컨테이너에서 나와주면 되는데 나올때는 ctrl or command + p + q를 사용해야 컨테이너가 중지되지 않는다. 우린 always 옵션을 주었기에 중지대로 다시 실행되겠지만 주의해주자.

 

이제 spring properties에서 mysql에 연동해보자.

 

application.properties

 

```

# db source url
spring.datasource.url = jdbc:mysql://localhost:3333/study?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul

# db response name
spring.datasource.username = root

# db response password
spring.datasource.password = 1234

spring.jpa.show-sql=true

```

 

이렇게되면 container의 mysql과 연동이 된것을 확인가능하다.

Comments