상황
현재 개발 중인 서비스에는 1분 배치 단위로 작동하는 스케줄러가 존재한다.
사용자의 알약 복용 스케줄에 맞춰서 알림을 보내주는데, 개발 서버에 배포 후 테스트 하는 과정에서 복용 시간이 지났는데도 알림이 전송되지 않고 기록도 남지 않는 문제가 발생하였다.
처음에는 알림을 보내주는 과정에서 문제가 발생하였다고 생각하였지만,
알림 전송에 실패하는 경우에도 기록은 남기도록 로직을 작성하였기에, 복용 시간을 스캔하는 과정에서 문제가 있다고 생각하였다.
문제를 디버깅한 결과, 개발 서버의 컨테이너 시간이 UTC(세계 협정시)였기 때문에 스케줄러가 해당 루틴을 찾지 못했었던 것이다.
데이터베이스에 복용 루틴을 utc를 고려한 timestamptz으로 변경하는 방법도 있지만, 국내에서만 출시를 할 계획이기 때문에, 스케줄러가 실행되는 환경의 시간을 바꾸기로 하였다.
따라서 애플리케이션을 빌드할 때 표준시간을 변경, 적용하는 방법을 정리하였다.
Dockerfile 변경
아래는 자바 애플리케이션을 빌드하기 위해 작성한 dockerfile이다.
Asia/Seoul 시간을 사용하도록 설정을 추가하였다.
# ======== 1단계: Build Stage ========
FROM gradle:8.5-jdk21 AS builder
WORKDIR /app
COPY . .
# 캐시를 활용한 build 속도 최적화
RUN gradle clean build -x test
# ======== 2단계: Run Stage ========
FROM eclipse-temurin:21-jre as runtime
WORKDIR /app
# 한국 시간대 설정
ENV TZ=Asia/Seoul
RUN apt-get update && apt-get install -y tzdata && \
ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 빌드 결과 JAR 복사
COPY --from=builder /app/build/libs/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]
1. ENV TZ=Asia/Seoul
사용할 시간대를 환경 변수로 선언하였다.
2. apt-get update && apt-gret install -y tzdata
이미지 빌드시 timezone 설정 패키지를 설치하도록 설정하였다.
3. ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
/usr/share/zoneinfo/Asia/Seoul 디렉터리를 /etc/localtime에 심볼릭 링크로 연결하였다.
이제 컨테이너 내부에서 현재 시간을 서울 기준으로 인식한다.
또한 시스템 재부팅되는 상황에서도 유지되도록 /etc/timezone에 내용을 작성하였다.
결론
이미지를 빌드하고 컨테이너 재배포를 한 결과 스케줄러의 복용 루틴 시간 대 인식이 잘되는 것을 확인하였다.
시스템에서 추가로 로그를 수집하는데, 로그가 발생한 시간대를 더 수월하게 판단하기 위해서
기본적으로 TimeZone을 설정하는 것이 필요하다는 생각이 들었다.
'Docker, Container' 카테고리의 다른 글
[Docker] Springboot 이미지 최적화 (0) | 2025.03.28 |
---|---|
[Linux] Docker, Docker Compose 설치 (0) | 2025.03.26 |