서론
프로젝트를 진행하면서 상용-개발의 데이터베이스 차이로 인해 업데이트 후 기능들이 작동하지 않는 경우가 종종 발생했다. 어떻게 하면 문제를 해결할 수 있을까 고민하던 중, Flyway라는 라이브러리를 알게 되었고 프로젝트에 적용하였다.
Flyway를 적용한 후에는 사용 방법이 두 가지 떠올랐다. 첫 번째 방법은 배포 전 또는 개발 중간에 테이블에 변화가 있으면 개인이 개별적으로 인지하고 로컬에서 테스트하는 것이며, 두 번째 방법은 CICD 과정에서 FlywayApplication을 실행하여 Entity 클래스와 DB Table이 일치하지 않으면 에러를 발생시켜 배포 중단 작업을 수행하는 것이다.
두 가지 방법 중에서 CICD 과정에서 FlywayApplication을 실행시키는 방법을 선택했다. 이 방법의 이점은 다음과 같다.
- Entity-Table 매핑이 잘못되었을 경우, 빌드/배포 과정에서 빠르게 검출할 수 있다.
- 개발자들이 직접 테스트를 수행하지 않아도 되므로, 개발 시간을 절약할 수 있다.
- 개발자들이 일관된 방식으로 Entity-Table 매핑을 수행하도록 유도할 수 있다.
프로젝트 추가 설정
FlywayApplication.java
@EntityScan(basePackages = {"co.dalicious.*"})
@SpringBootApplication
public class FlywayApplication {
public static void main(String[] args) {
ConfigurableApplicationContext ctx = SpringApplication.run(FlywayApplication.class, args);
ctx.close();
}
}
FlywayApplication은 서버에 계속 띄워질 필요가 없다. 매핑 테스트에 문제가 없다는 것만 확인하고 종료하면 되는 애플리케이션이기 때문이다. 따라서 실행 후 에러가 없다면 바로 종료하는 코드를 삽입했다.
이 외의 프로젝트 셋팅은 여기를 참고하면 된다.
CICD 플로우
처음에 내가 머리 속으로 그린 CICD 플로우는 아래와 같았다.
하지만 문제가 발생했다. FlywayApplciation 실행이라는 JOB을 추가하면서 필요한 설정 파일만 삽입해서 빌드를 하다보니, JOB1과 JOB2에서 두 번 빌드가 발생했다. 따라서 5~6분 정도 걸리던 배포 시간이 10분으로 늘어나버린 것이다.
Build를 한 번만 진행하기 위해, Job으로 분리하는 것이 아닌, Step으로 분리하여 배포 시간을 줄였다.
빌드시간은 10분에서 6분 가량으로 감소했다.
Github Actions 스크립트 파일 수정
서버에 띄워줄 필요가 없었기 때문에 Docker Image를 빌드해줄 필요도 없었다.
name: 개발서버 배포
on:
push:
branches: [ "develop" ]
permissions:
contents: read
jobs:
build-image:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: JDK 17 세팅
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'adopt'
.....
- name: gradlew 실행 권한 추가
run: chmod +x gradlew
- name: Gradle 빌드
run: ./gradlew build
- name: 빌드 및 FlywayApplication (dev) 실행
run: |
cd ./data-flyway/build/libs/
java -Dspring.profiles.active=dev -jar data-flyway.jar
개발서버와 상용서버의 DB 주소가 다르기 때문에 설정 파일을 구분할 필요가 있었다. 이를 위해서는 어떤 파일을 활성화 시킬 건지가 중요했기 때문에 java -Dspring.profiles.active=dev -jar data-flyway.jar
부분이 필요했다.