Docker alpine 이미지 사용 시 Timezone 설정

검프·2021년 7월 12일
2
post-thumbnail

Docker 컨테이너를 위한 베이스 이미지로 알파인Alpine^{Alpine} 리눅스를 자주 사용합니다. 여러 장점이 있을 수 있겠지만 배포 용량이 아주 작아진다는 점 때문에 애용하고 있습니다.

최근 Go 언어로 개발한 애플리케이션에서 스케줄러를 이용한 주기적인 작업이 필요해서 robfig/cron 패키지를 사용했습니다. 개인적으로 CRON 표현식에 기반한 스케줄러를 즐겨 사용하는 편입니다. 대략 아래와 같은 코드를 로컬에서 테스트 후 잘 동작하는 것을 확인했는데요, 개발 환경에 알파인 이미지 기반으로 패키징하여 배포를 하고 나니까 정상적으로 동작하지 않았습니다.

import "github.com/robfig/cron/v3"
...
c := cron.New()
_, _ = c.AddFunc("1 1 * * *", func() {
	fmt.Println("Execute Job!")
})
c.Start()

몇 가지 간단히 확인해보고 Docker 컨테이너의 타임존Timezone^{Timezone}이 UTC로 설정되어 있어서 KST를 의도하고 설정한 시간에 실행이 안 되고 있다는 사실을 알 수 있었습니다. 그래서 아래와 같이 Cron 스케줄을 추가할 때 타임존 설정을 추가해서 배포를 진행했습니다.

import "github.com/robfig/cron/v3"
...
loc, err := time.LoadLocation("Asia/Seoul")
if err != nil {
	panic(err) // unknown time zone Asia/Seoul
}

c := cron.New(cron.WithLocation(loc))
_, _ = c.AddFunc("1 1 * * *", func() {
    fmt.Println("Execute Job!")
})
c.Start()

실행을 해보니 unknown time zone Asia/Seoul 오류가 발생하면서 panic이 되었습니다. 알파인 이미지에 Asia/Seoul 타임존 설정이 없어서 발생한 오류였습니다. 알파인 이미지는 기본 UTC로 타임존이 설정되어 있고, 용량을 줄이기 위해서 다른 타임존에 대한 설정은 포함하지 않고 있습니다.

그래서 타임존 패키지를 설치하고 Asia/Seoul 타임존을 추가하는 형태로 해결할 수 있었습니다. Dockerfile에 아래 레이어를 추가합니다.

RUN apk --no-cache add tzdata && \
	cp /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
	echo "Asia/Seoul" > /etc/timezone \
	apk del tzdata

알파인의 패키지 관리자인 apk를 이용해서 tzdata 패키지를 설치합니다. 그리고 Asia/Seoul 타임존을 컨테이너의 타임존으로 설정합니다. 설정 후 tzdata 패키지는 필요 없으므로 삭제해 줍니다.
설정 후 실행하면 정상적으로 타임존 설정이 적용됩니다 :)

참고 자료

profile
권구혁

1개의 댓글

comment-user-thumbnail
3일 전

본문대로 작성하니 /etc/timezone 파일 내용이 다음과 같이 되고, tzdata 패키지 삭제가 안 되네요!

$ cat /etc/timezone
Asia/Seoul apk del tzdata

아마 3번 라인 끝에 && 기호가 빠져서 그런것같습니다.

그리고 참고자료 링크를 가보니 아래와 같이 심볼릭링크 하나만 만들어줘도 타임존 설정은 잘 되는것같아요.

RUN apk --no-cache add tzdata && \
    ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime && \
    apk del tzdata
답글 달기