Docker 컨테이너를 위한 베이스 이미지로 알파인 리눅스를 자주 사용합니다. 여러 장점이 있을 수 있겠지만 배포 용량이 아주 작아진다는 점 때문에 애용하고 있습니다.
최근 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 컨테이너의 타임존이 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
패키지는 필요 없으므로 삭제해 줍니다.
설정 후 실행하면 정상적으로 타임존 설정이 적용됩니다 :)
본문대로 작성하니
/etc/timezone
파일 내용이 다음과 같이 되고,tzdata
패키지 삭제가 안 되네요!아마 3번 라인 끝에
&&
기호가 빠져서 그런것같습니다.그리고 참고자료 링크를 가보니 아래와 같이 심볼릭링크 하나만 만들어줘도 타임존 설정은 잘 되는것같아요.