글 작성자: beaniejoy
  • Overview
  • flyway docker image
  • flyway 관련 프로젝트 내부 디렉토리 설정
  • docker 실행해서 migration 확인하기
  • 정리

 

📌 1. Overview

새로운 사이드 프로젝트 진행을 하면서 flyway를 이용해 db migration을 진행하고 있습니다. 로컬 영역에서 먼저 db 테이블을 flyway로 관리하도록 환경을 구성하려고 하는데요. 추후에 이를 가지고 AWS 같은 클라우드 서버에도 db migration하는데 사용해볼 생각입니다.

이번 게시물의 목표는 다음과 같습니다.

  • flyway를 이용해 command-line 방식으로 db migration하기
  • docker를 사용해 flyway 자동 적용해보기

 

📌 2. flyway docker image

docker hub에 등록된 flyway image를 확인해보면 설정방법과 docker 적용방법이 있습니다. 
(docker hub flyway image)

 

Docker Hub

 

hub.docker.com

docker의 flyway를 컨테이너화해서 프로젝트에 migration하는 여러 방법이 존재하겠지만 저는 그 중에서 volume을 이용해 flyway config 파일과 migration 대상인 sql파일들을 flyway container 내부디렉토리와 매핑하는 방식으로 설정해볼 계획입니다.

 

📌 3. flyway 관련 프로젝트 내부 디렉토리 설정

project
├── env
    └── mysql.env (mysql 도커 환경변수)
├── flyway 
    ├── conf
    	└── flyway_main.conf (migration 관련 flyway 설정내용)
    └── db-migration
    	├── V001_Create_table_name.sql (migration 대상 sql 파일들)
    	└── ...
└── docker-compose.yml (docker compose 설정)

flyway 관련된 파일들만 표시한 디렉토리 구조도입니다. 설정내용들 하나하나 살펴보겠습니다.

MYSQL_DATABASE=test-schema
MYSQL_ROOT_PASSWORD=dev

mysql.env 내용입니다. docker compose에서 mysql 컨테이너에 적용할 db 관련 환경변수입니다. 사용할 스키마와 root password만 설정해줬습니다.

flyway.url=jdbc:mysql://db-mysql:3306/test-schema
flyway.user=root
flyway.password=dev
flyway.driver=com.mysql.cj.jdbc.Driver

flyway_main.conf 내용입니다. flyway commad-line 방식으로 migrate를 할 때 사용되는 config 파일입니다. 여기에는 migration 대상이 될 db schema 정보를 담아야 합니다.
url에 db-mysql:3306 으로 되어있는 것은 이후에 나올 docker compose 설정파일에 있는 mysql container 명입니다. flyway도 같은 docker compose 파일 안에 설정할 것이기 때문에 컨테이너를 통해 내부에서 mysql과 flyway container가 연결되어있기에 컨테이너명으로 설정한 것입니다.

CREATE TABLE `cafe` (
    `cafe_id` binary(16) NOT NULL COMMENT '카페식별번호',
    `name` varchar(20) NOT NULL COMMENT '카페명',
    `address` varchar(100) NOT NULL COMMENT '카페 주소',
    `phone_number` varchar(11) NOT NULL COMMENT '카페 전화번호',
    `total_rate` float NOT NULL COMMENT '카페 종합 평가 점수',
    `description` varchar(255) COMMENT '카페 상세설명',
    `created_date` datetime NOT NULL COMMENT '카페 등록날짜',
    `updated_date` datetime COMMENT '카페 수정날짜',
    PRIMARY KEY (`cafe_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

V001_Create_table_name.sql과 같은 migration할 sql 파일입니다. DDL 쿼리 내용을 담고 있어야 합니다.

version: "3.8"
services:
  db-mysql:
    image: mysql:5.7.34
    ports:
      - "3306:3306"
    env_file:
      - env/mysql.env
  migration:
    image: flyway/flyway:7.5.1
    command: -configFiles=/flyway/conf/flyway.config -locations=filesystem:/flyway/sql -connectRetries=60 migrate
    volumes:
      - ${PWD}/flyway/db-migration/main:/flyway/sql
      - ${PWD}/flyway/conf/flyway_main.conf:/flyway/conf/flyway.config
    depends_on:
      - db-mysql

docker-compose.yml 파일 내용입니다. 여기서 중요한 것은 flyway image를 flyway/flyway로 하면 가장 최신 버전인 (현재기준) 8버전을 사용하게 됩니다. 제가 프로젝트에서 사용하고 있는 mysql 버전은 5.7.x 버전인데 이대로 적용하면 호환성 이슈가 발생합니다.

위의 스크린샷에서 볼 수 있듯이 MySQL 5.7 버전은 Flyway Community Edition에서 지원하지 않는다는 내용이 있습니다. 그래서 Teams Edition으로 사용하라고 지시해주는데요. 저는 그냥 flyway image 버전을 downgrade해서 사용했습니다. (7.5.1버전)

 

📌 4. docker 실행해서 migration 확인하기

$ docker-compose up --build

프로젝트를 한번 실행해봅시다.

docker-compose.yml 파일에 설정한 컨테이너들이 올라오면서 위의 그림과 같이 Migration Success 내용이 나와야 정상적으로 등록이 된 것입니다.

MySQL Workbench를 통해 확인해보면 위와같이 flyway 관련 설정내역을 담은 테이블과 함께 migration sql 파일에 설정해둔 테이블들이 등록되어 있는 것을 확인할 수 있습니다.

command: -configFiles=/flyway/conf/flyway.config -locations=filesystem:/flyway/sql -connectRetries=60 migrate

여기서 다시 docker compose 설정파일을 보면 migration container 실행구문에 -connectRetries=60이 있습니다. 처음에 해당 flyway 옵션 없이 docker를 띄웠는데 flyway 적용 에러가 발생했었습니다. 내용은 연결하려는 MySQL connection 정보가 없다는 것이었습니다.

확인해본 결과 depends_on으로 컨테이너 생성 순서를 정해도 mysql 서버가 완전히 올라오는 것과 flyway 구문이 실행되는 것에 대해서 순서가 보장되지 않았습니다. 즉 mysql 서버가 완전히 올라오기 전에 flyway가 실행되기 때문에 connection 정보를 찾을 수 없었던 것입니다. 이 부분에 대해 해결책을 찾아보니 -connectRetries 옵션 방법이 있었습니다.

connectRetries : Maximum number of retries when attempting to connect to the database 이렇게 설명하고 있는데요. DB에 연결하는 최대 시도 횟수를 설정한다고 보면 됩니다. DB가 연결될 때까지 시도하는 최대 횟수라고 보면 될 것 같네요.

 

📌 정리

docker를 이용해 flyway 적용을 자동화하는 프로세스를 구축해보았습니다. 하지만 이 내용만으로는 AWS 같은 클라우드 서버 배포 때 여러 문제가 발생할 것입니다. 우선 배포될 서버의 환경이 바뀌기 때문에 config 파일 내용과 DB 설정 내용도 다릅니다.

이 부분은 EC2 서버 내부에 특정지어둔 디렉토리에 해당 env파일과 conf파일을 미리 만들어두고 CI/CD 프로세스에서 이 파일들을 참조하도록 설정하면 되지 않을까 싶네요. 이부분도 한 번 적용해보고 정리해보겠습니다.

참고용으로 위의 내용들을 담은 github repository 링크 걸어두겠습니다.
https://github.com/beaniejoy/back-overall-repository/tree/main/docker-dbmigration-flyway

 

GitHub - beaniejoy/back-overall-repository: 🧪 Back-end Study & Test Repository, which manages and tests various frameworks, l

🧪 Back-end Study & Test Repository, which manages and tests various frameworks, libraries and modules, that consists of directories named by each topic. - GitHub - beaniejoy/back-overall-reposi...

github.com

 

참고

Running PostgreSQL and Flyway with Docker Compose

 

Running PostgreSQL and Flyway with Docker Compose

Run PostgreSQL locally and apply schema changes using Flyway. Let’s see how to do it without messing up with your local environment, thanks to Docker Compose.

writeitdifferently.com

제가 참고했던 flyway docker compose 관련 글인데요. 깔끔하게 정리된 글이라 보면 좋을 것 같습니다.