docker-compose로 일관된 spring boot 로컬 개발 환경 구성하기

Gongmeda·2023년 11월 6일
6
post-thumbnail

docker, docker-compose를 사용한 이유

환경 격리

docker의 가장 강력한 역할 중 하나는 환경 격리라고 생각합니다.

제 로컬 환경에는 여러 프로젝트들이 하나의 로컬에 설치된 MySQL DB를 사용하고 있는데요.
기본적으로 하나의 DB를 사용하는 것은 문제가 없지만, 특정 프로젝트에서 필요하여 DB의 설정을 바꾸는 경우 다른 프로젝트에 예상치 못한 영향을 줄 가능성이 있다고 생각했습니다.

또한, 설치된 DB의 버전이 서로 다를 경우에도 문제가 생길 수 있습니다.
예를 들어 저는 설치된 MySQL 버전이 8.0.33 이었고, 제 팀원은 8.0.32 였습니다.
이 경우에는 마이너한 차이라 실질적으로 문제는 없었겠지만, 버전 차이가 컸다면 문제가 생길 수 있었을 것이고 Spring 프로젝트의 DB connector 의존성 버전도 서로 달라지게 되니 골치가 아파집니다.

seamless한 개발 환경 세팅

이전에 docker를 사용하지 않은 프로젝트에서는 스프링 부트 설정 파일인 applciation.yml 을 협업하는 사람들이 각자 환경에 맞게 수정하여 사용해야 했습니다.

# application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test	# test라는 database를 만들어줘야 하네...
    username: root
    password: password						# 내 root 환경 비번은 ****인데...
    driver-class-name: com.mysql.cj.jdbc.Driver

docker-compose로 환경을 구성하면 아래처럼 환경을 올리면서 초기화 단계에서 원하는 database를 생성할 수 있으며, 포트도 임의로 바꿀 수 있습니다.
따라서, 팀원이 코드를 pull 받아 명령어로 환경을 올리기만 하면 추가로 수정해야 하는 부분이 없는 것 입니다.

# application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:43306/test
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
# docker-compose.yml

services:
  mysql:
    image: mysql:8.0.33
    ports:
      - 43306:3306
    volumes:
      - ./db/mysql/data:/var/lib/mysql
      - ./db/mysql/init:/docker-entrypoint-initdb.d
    command:
      - '--character-set-server=utf8mb4'
      - '--collation-server=utf8mb4_unicode_ci'
    environment:
      MYSQL_ROOT_PASSWORD: password		# 구성활 MySQL의 root 비밀번호
      MYSQL_DATABASE: test				# 기본으로 생성할 database명

또한, 이후에 프로젝트에서 Redis를 사용할 예정이 되어 있었기 때문에 MySQL과 Redis를 함께 묶어서 관리할 필요가 있었습니다. 이러한 용도로는 docker-compose가 최적이었습니다.

환경 구성 방법

1. docker-compose.yml 작성

services:
  mysql:
    image: mysql:8.0.33
    ports:
      - {port}:3306
    volumes:
      - ./db/mysql/data:/var/lib/mysql
      - ./db/mysql/init:/docker-entrypoint-initdb.d
    command:
      - '--character-set-server=utf8mb4'
      - '--collation-server=utf8mb4_unicode_ci'
    environment:
      MYSQL_ROOT_PASSWORD: {root_password}
      MYSQL_DATABASE: {database_name}

프로젝트 루트에 docker-compose.yml 파일을 작성합니다.

위의 volumes 를 주의해야 하는데요.

./db/mysql/data:/var/lib/mysql./db/mysql/data 폴더를 MySQL의 /var/lib/mysql 로 사용하겠다는 뜻 입니다. 즉, 환경을 올리면 프로젝트 루트에 db 라는 폴더가 생긴다는 것이죠.

이를 설정해주지 않는다면 기존에 MySQL이 설치되어 있는 환경에서는 설치된 MySQL의 데이터 파일을 공유하게 되어 컨테이너를 통해 MySQL에 접근해도 기존 database들이 남아있죠.
그래서 격리를 하기 위해 데이터 파일을 프로젝트 루트의 db 폴더에 생성하도록 한 것입니다.

저는 해당 환경의 MySQL에 접근하는 포트인 {port}를 43306으로 설정했습니다.
이는 다른 팀원들의 환경에서도 사용하지 않는 포트여야 합니다.

2. build.gradle 수정

dependencies {
	runtimeOnly "com.mysql:mysql-connector-j:8.0.33
}

MySQL 이미지의 버전에 맞게 의존성을 설정합니다

3. application.yml 수정

# application.yml

spring:
  datasource:
    url: jdbc:mysql://localhost:{port}/{database_name}
    username: root
    password: {root_password}
    driver-class-name: com.mysql.cj.jdbc.Driver

docker-compose.yml 에서 설정한 값들과 일치하도록 수정해줍니다.

4. 환경 올리기/내리기

CLI로 환경을 올리고 내릴 수 있습니다.

# 프로젝트 루트에서

# 환경 올리기 (데몬으로)
docker-compose up -d

# 환경 내리기
docker-compose down

참고

profile
백엔드 깎는 장인

1개의 댓글

comment-user-thumbnail
2024년 4월 20일

안녕하세요. MySQL 말고 Spring Boot를 올리는 건 없을까요? 설명 잘봤습니다

답글 달기