はじめに
どうも僕です。
業務でDockerを使うことがあるのですが、golang
のコンテナでcron
の実行をする際、タイムゾーンがUTC
だったのでJST
に変えようとしたところ、結構つまづいたのでメモっておきます。
概要
golang
にてcronを使って毎日特定の時刻に関数を走らせたい!
↓
しかしタイムゾーンがUTCだ!!
↓
どうにかせんといかん。
結論
先に結論を言うと、 Dockerfileに次のコードを追加する。
FROM golang:1.19
WORKDIR /usr/src
# これを追加↓
ADD https://github.com/golang/go/raw/master/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip
そしてコード
package main
import (
"fmt"
"log"
"os"
"time"
)
func main() {
os.Setenv("TZ", "Asia/Tokyo")
log.Println("Now time is: ", time.Now())
local, err := time.LoadLocation("Local")
if err != nil {
log.Println(err)
}
fmt.Println(local)
}
root@c74f69be4f71:/usr/src# go run main.go
2024/01/19 12:29:18 Now time is: 2024-01-19 12:29:18.482109833 +0900 JST m=+0.000930959
Local is: Asia/Tokyo
解説
DockerのTimeZoneに関しては色々な設定があると思います。
設定の際にやってみたこととしては
- ホストOSのTimezoneをJSTにしてVolumeでDockerに渡す
- DockerfileにTZ:Asia/Japanを入れた
- Dockerコンテナ内で
date
コマンドからJSTなるようにした - Dockerfileで
COPY --from=builder /usr/share/zoneinfo/Asia/Tokyo /usr/share/zoneinfo/Asia/Tokyo
をしてみた
等々、いろいろありますが、問題点がいくつかあるようです。
ホストOSのTimezoneをJSTにしてVolumeでDockerに渡す
Dockerコンテナ内でdateコマンドからJSTなるようにした
あまり推奨されてなさそう
$ docker compose exec golang bash
# コンテナに入る
$ date
Fri Jan 19 12:45:47 JST 2024
こうなってもgolangがTimezoneを参照しに行く場所が違うため意味がない
DockerfileにTZ:Asia/Japanを入れた
TZが対応していないDocker Imageもあるから必ずできるわけではない
DockerfileでCOPY --from=builder /usr/share/zoneinfo/Asia/Tokyo /usr/share/zoneinfo/Asia/Tokyoをしてみた
DockerImageがalpine
のような軽量のものでは/usr/share/zoneinfo
が存在せず、
docker compose build
の際にエラーが出る
結論2
Dockerfileに
ADD https://github.com/golang/go/raw/master/lib/time/zoneinfo.zip /usr/local/go/lib/time/zoneinfo.zip
を追加してgolangがTimezoneを参照できるところにTimezoneの情報を置いて、os.Setenv("TZ", "Asia/Tokyo")
すればいい。
参考になったリンク