Docker 上の Almalinux のタイムゾーン設定について

経緯

AlmaLinux ベースの自作LAMP環境構築用 Docker で WordPress を動かしたところ、投稿が「予約投稿の失敗」となってしまい正常に投稿できない現象に遭遇したため対処。

現象

今までの設定で発生していた現象
今までの設定で発生していた現象

今までの Docker Compose 環境で発生していた現象が上述の画像。普通に投稿したにも関わらず、「予約投稿の失敗」となってしまいます。

困ったことに WordPress の管理画面で見ると日時はずれていない (WordPress インストール時のサンプル投稿「Hello World!」の投稿日時とほぼ同じ) ので、ぱっと見原因が掴みづらいところ。

ちなみに、 wp_posts のテーブルを直接見たところ、 post_date, post_date_gmt, post_modified, post_modified_gmt が全て同じ日時になっていました。

……あれ、 _gmt 系はグリニッジ標準時刻なので日本の時刻とは9時間ずれるはずでは……。ということで、どうもこの辺りが宜しくなさそうです。

なお、この時の Dockerfile 等の各種設定は次のようになっていました。

Dockerfile (共通)

RUN \cp -pf /usr/share/zoneinfo/Japan /etc/localtime

php.ini

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = 'Asia/Tokyo'

my.cnf 等

MySQL 側では特に指定なし。

変更

これらの設定を次のようにしました。

Dockerfile (共通)

RUN rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-AlmaLinux \
    && dnf -y update && dnf -y install \
    # 略
    # timezone
    glibc-locale-source \
    # locale, timezone
    && localedef -f UTF-8 -i ja_JP ja_JP.UTF-8 \
    && ln -sf /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
# local & timezone
ENV LANG="ja_JP UTF-8" \
    LANGUAGE="ja_JP:ja" \
    LC_ALL="ja_JP.UTF-8" \
    TZ="Asia/Tokyo"

やり方を大幅に変更。強制コピーで localtime ファイルを上書きするのではなく、段取りを踏んで設定するようにしました。

php.ini

[Date]
; Defines the default timezone used by the date functions
; http://php.net/date.timezone
;date.timezone =
date.timezone = 'Asia/Tokyo'

変わらず。

my.cnf 等

こちらも変わらず。

検証

新しい設定方法で投稿した場合の挙動
新しい設定方法で投稿した場合の挙動

新しい方法で設定した Docker 環境上に先程と同様 WordPress をインストールして記事を投稿すると、無事投稿が公開されました。

このとき、 wp_posts のテーブルを直接見ると、 post_date, post_modified は同じ日時、 post_date_gmt, post_modified_gmt は -9時間の日時になっていました。

やはりここがおかしかったようです。

続・検証

さて、それではこの時刻の狂いはどこに起因しているのでしょうか。

Webサーバのみ新しい設定方法で投稿した場合の挙動
Webサーバのみ新しい設定方法で投稿した場合の挙動

Webサーバの Dockerコンテナ のみ今回の新しい方法で localtime を設定した場合。OKですね。

DBサーバのみ新しい設定方法で投稿した場合の挙動
DBサーバのみ新しい設定方法で投稿した場合の挙動

DBサーバの Dockerコンテナ のみ今回の新しい方法で localtime を設定した場合。NGです。

ということで、原因は Webサーバ 側にありそうです。

Webサーバでの date

ただ、 Webサーバ のコンテナで date コマンドを打っても日時は正しい日時が返ってくるのですよね。

設定方法が未変更の状態の Webサーバ コンテナ

# php -r 'echo date_default_timezone_get() . PHP_EOL; echo date("y-m-d H:i:s") . PHP_EOL;'
Asia/Tokyo
22-02-13 19:06:21
# date
Thu Feb 13 19:06:28 JST 2022

設定方法を変更した状態の Webサーバ コンテナ

# php -r 'echo date_default_timezone_get() . PHP_EOL; echo date("y-m-d H:i:s") . PHP_EOL;'
Asia/Tokyo       
22-02-13 19:16:50
# date
2022年  2月 13日 日曜日 19:16:56 JST

ご覧の通り時刻は正常……ってあれ、確かに日時は正常ですが、出力フォーマットが異なっています。

どうやら今までの設定変更ではやはり不完全な部分があるようです。どこが、というところまでは追い切れていないですが、ここまでの検証で確かに今までの設定方法では宜しくないであろう、ということが断片的に表われているので、ここは大人しく新しい設定方法に変更していった方が良さそうです。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。