웹 개발
cron 작업 시간이 9시간 어긋나는 이유
cron은 서버 시스템 timezone을 그대로 따르기 때문에, UTC로 세팅된 서버에서 한국 시각 기준으로 스케줄링하면 반드시 어긋난다.
서버에 cron을 설정하고 나서 "왜 9시에 실행되지 않고 0시에 실행되지?" 하는 상황을 한 번쯤 겪었을 것이다. 원인은 거의 항상 timezone이다.
시스템 timezone 먼저 확인한다
cron은 별도 설정이 없으면 시스템 timezone을 기준으로 실행된다. Hetzner, DigitalOcean, AWS EC2 등 대부분의 클라우드 인스턴스는 기본값이 UTC다. 한국(KST)은 UTC+9이므로, UTC 기준 0시는 KST 기준 9시다.
# 현재 시스템 timezone 확인
timedatectl status
# 또는
cat /etc/timezone
출력에 Time zone: UTC 가 보이면 cron도 UTC 기준으로 돈다.
crontab에서 timezone을 직접 지정하는 방법
/etc/crontab 또는 crontab -e로 연 사용자 crontab 최상단에 CRON_TZ를 선언하면 해당 파일 내 모든 작업의 기준 timezone을 바꿀 수 있다.
CRON_TZ=Asia/Seoul
# 매일 오전 9시(KST)에 실행
0 9 * * * /home/dev/scripts/backup.sh
CRON_TZ는 개별 항목이 아니라 파일 전체에 영향을 준다. 항목마다 다른 timezone이 필요하면 별도 파일로 분리하는 편이 낫다.
systemd timer를 쓴다면
systemd .timer 유닛은 OnCalendar 값이 기본적으로 로컬 시각 기준이지만, 서버 timezone에 따라 달라진다. UTC로 고정하고 싶으면 [Timer] 섹션에 명시한다.
[Timer]
OnCalendar=*-*-* 00:00:00 UTC
Persistent=true
KST 기준으로 명시하려면:
OnCalendar=Asia/Seoul *-*-* 09:00:00
실수를 줄이는 습관
cron 작업을 추가할 때마다 주석에 어느 timezone 기준인지 명시해두는 게 좋다. 몇 달 뒤 같은 파일을 볼 때 "이게 UTC야, KST야?" 하고 헷갈리는 상황을 방지할 수 있다.
CRON_TZ=Asia/Seoul
# [KST] 매일 02:00 - DB 백업
0 2 * * * /home/dev/scripts/db-backup.sh
# [KST] 매주 월요일 10:00 - 주간 리포트 생성
0 10 * * 1 /home/dev/scripts/weekly-report.sh
timezone 관련 실수는 로그에서 바로 잡히지 않는다. 작업이 예상 시각에 실행됐는지는 grep CRON /var/log/syslog 또는 journalctl -u cron 으로 확인할 수 있다.