Skip to content

build: Docker 운영 환경과 UTC 저장 기준 정비 - #1

Merged
Seongbin-Choo merged 3 commits into
mainfrom
docker-production-hardening
Sep 1, 2026
Merged

Seongbin-Choo merged 3 commits into
mainfrom
docker-production-hardening

Conversation

@Seongbin-Choo

@Seongbin-Choo Seongbin-Choo commented Sep 1, 2026 •

Copy link
Copy Markdown
Owner

문제

실행 환경에 따라 달라지는 시간값

LocalDateTime과 MariaDB DATETIME(6)을 사용하면서 JVM 기본 시간대에 의존하고 있었습니다.

로컬 IntelliJ 환경은 KST, Docker 운영 환경은 UTC를 사용했기 때문에 같은 코드가 실행 환경에 따라 9시간 차이 나는 값을 저장할 수 있었습니다.

클라이언트가 안내 문구에 의존하는 문제

분석할 수 없는 로그에 대해 백엔드는 한글 안내 문구만 반환했습니다. 플러그인이 상황을 구분하려면 사람이 읽는 문장을 파싱해야 했고, 문구나 언어가 변경되면 클라이언트 로직도 깨질 수 있었습니다.

반복되는 Docker 의존성 다운로드

소스 코드를 복사한 뒤 Gradle 빌드를 실행하고 캐시를 유지하지 않아, 코드 한 줄만 변경해도 의존성을 다시 확인하거나 내려받을 수 있었습니다.

운영 환경의 안전하지 않은 Flyway 설정

운영 환경에서 baseline-on-migrate=true를 사용하면 마이그레이션 이력이 없는 기존 스키마를 정상 상태로 간주할 수 있습니다. 잘못 연결된 데이터베이스를 빠르게 발견하지 못할 위험이 있었습니다.

판단과 선택

저장 시간은 UTC로 통일

JVM 기본 시간대와 Hibernate JDBC 시간대를 모두 UTC로 고정하고, MariaDB와 백엔드 컨테이너에도 UTC를 적용했습니다.

Compose의 TZ만 변경하는 방식은 선택하지 않았습니다. 이 방법으로는 IntelliJ나 로컬 Gradle 실행 시 개발자 PC의 시간대를 계속 상속하기 때문입니다.

Asia/Seoul로 통일하는 방법도 검토했지만, 저장 데이터를 특정 지역에 종속시키면 서버 이전이나 다중 지역 운영 시 다시 변경해야 하므로 UTC를 선택했습니다.

기존 데이터 및 API와의 호환성을 위해 현재의 LocalDateTime과 DATETIME(6) 구조는 유지했습니다. Instant 또는 OffsetDateTime 전환은 별도 마이그레이션으로 다루는 것이 안전하다고 판단했습니다.

안정적인 guidanceCode 제공

사람이 읽는 guidance 문구와 함께 기계가 처리할 수 있는 guidanceCode를 반환하도록 변경했습니다.

플러그인은 코드를 기준으로 메시지를 현지화할 수 있으며, 기존 클라이언트나 알 수 없는 신규 코드는 기존 안내 문구를 표시하는 방식으로 호환성을 유지합니다.

Docker 빌드 캐시 활용

BuildKit 캐시 마운트로 Gradle Wrapper와 의존성 캐시를 유지하도록 했습니다.

Docker 빌더 단계는 매번 격리된 파일시스템에서 시작하므로 실질적인 이점이 없는 clean 작업은 제거했습니다.

운영 DB는 잘못된 스키마에서 즉시 실패

개발 환경은 기존 로컬 DB 호환성을 위해 baseline-on-migrate=true를 유지했습니다.

운영 환경은 false로 설정하여 Flyway 이력이 없는 예상 밖의 스키마에 연결되면 조용히 넘어가지 않고 즉시 실패하도록 했습니다.

변경 내용

  • 분석 준비 상태를 나타내는 guidanceCode 추가
  • 백엔드와 MariaDB의 Docker Compose 셀프 호스팅 환경 구성
  • JVM, Hibernate JDBC 및 컨테이너 시간대를 UTC로 통일
  • 운영 환경의 Flyway 자동 baseline 비활성화
  • Gradle BuildKit 캐시 적용 및 불필요한 clean 제거
  • CI에 Docker Compose 구성 및 이미지 빌드 검증 추가
  • MIT 라이선스와 프로젝트 운영 문서 추가

검증

  • ./gradlew test bootJar
  • 전체 49개 테스트 중 46개 통과, 조건부 테스트 3개 제외
  • docker compose --env-file .env.example config --quiet
  • Docker 이미지 빌드 성공
  • MariaDB 및 백엔드 컨테이너 Health Check 통과
  • /api/v1/health 응답 {"status":"UP"} 확인
  • 두 컨테이너가 UTC를 사용하는지 확인
  • Flyway 스키마 버전 4 적용 확인
  • 명시적 시간, JPA Auditing 시간 및 DB 원시 값을 검증하는 UTC 통합 테스트 통과

업그레이드 주의사항

이 변경은 이전 버전에서 저장된 시간값을 자동으로 변환하지 않습니다.

개발용 데이터라면 필요한 데이터를 백업한 뒤 DB를 다시 생성할 수 있습니다. 기존 데이터를 유지해야 한다면 먼저 데이터가 실제로 어떤 시간대를 기준으로 저장됐는지 확인하고, 백업본에서 변환 결과를 검증해야 합니다.

과거 Docker 환경에서 저장된 데이터는 이미 UTC일 수 있고, 로컬 JVM에서 저장된 데이터는 다른 시간대일 수 있으므로 일괄적으로 9시간을 빼면 안 됩니다.

@Seongbin-Choo
Seongbin-Choo merged commit 803a4e4 into main Sep 1, 2026
2 checks passed
@Seongbin-Choo Seongbin-Choo changed the title build: harden Docker runtime and UTC persistence build: Docker 운영 환경과 UTC 저장 기준 정비 Sep 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant