Docker コンテナにデプロイされた Django のタイムゾーンの問題

Docker コンテナにデプロイされた Django のタイムゾーンの問題

現在、コンテナ デプロイメントは非常に成熟しています。当社のサービスの多くはコンテナ デプロイメントを使用しており、更新とリカバリは非常に便利です。ただし、より厄介な問題があります。それは、タイム ゾーンの処理です。通常、これは TZ 環境変数を挿入することで解決されますが、この処理方法は Django では機能しません。

Django でのタイムゾーン設定

Django の設定ファイル settings.py には、時間とタイムゾーンに関連する TIME_ZONE と USE_TZ という 2 つの設定パラメータがあります。 settings.py で設定した後、Django はローカル時間を正しく取得できると期待していましたが、実際は期待に反しています。これら 2 つの設定が何をするのか見てみましょう。

USE_TZ=真

USE_TZ が True に設定されている場合、Django はシステムのデフォルトのタイムゾーンを使用します。このとき、TIME_ZONE 設定は基本的に無効であり、設定されているかどうかに関係なく効果はありません。

USE_TZ=偽

USE_TZがFalseに設定されている場合

  1. TIME_ZONEはNoneに設定されています
  2. Djangoはデフォルトのタイムゾーンを引き続き使用します
  3. TIME_ZONEが別のタイムゾーンに設定されている場合

Windows を使用している場合、TIME_ZONE 設定は役に立たず、Django はローカル時間を使用します。他のシステムを使用している場合は、そのタイムゾーンの UTC 時間を使用します。

たとえば、USE_TZ = False、TIME_ZONE = 'Asia/Shanghai' に設定すると、上海の UTC 時間が使用されます。

この時点では、時間は適切だと思うかもしれませんが、実際はそうではありません。システムのタイムゾーン設定にも注意する必要があります。

Linux コンテナでのタイムゾーンの設定

私の現地時間は16:15で、Djangoの設定はUSE_TZ = False、TIME_ZONE = 'Asia/Shanghai'です。

コンテナの時間とタイムゾーンを表示するためにコンテナに入るときに、TZ=Asia/Shanghai 環境変数を挿入しないでください。

システム時間はUTCタイムゾーンで表示され、時刻は08:15で、ちょうど8時間の差です。

Django環境に入り、時間とタイムゾーンを表示します。

python manage.py シェル 
 
datetime から datetime をインポート 
日付時刻.now() 
# 出力 datetime.datetime(2021, 10, 8, 8, 24, 8, 289230) 
 
django.utilsからタイムゾーンをインポートする 
タイムゾーン.get_current_timezone_name() 
# 'Asia/Shanghai' を出力

環境変数 TZ=Asia/Shanghai を挿入します
コンテナに入ると時間とタイムゾーンが表示されます

システム時間はアジアタイムゾーンで表示されますが、時間は実際の現地時間ではなく、UTC 時間のままです。

Django環境に入り、時間とタイムゾーンを表示します。

python manage.py シェル 
 
datetime から datetime をインポート 
日付時刻.now() 
# 出力 datetime.datetime(2021, 10, 8, 8, 24, 8, 289230) 
 
django.utilsからタイムゾーンをインポートする 
タイムゾーン.get_current_timezone_name() 
# 'Asia/Shanghai' を出力 

ご覧のとおり、タイムゾーンは変更されていますが、コンテナ自体とDjangoの両方で時刻はUTC時間のままです。

オンラインで検索すると、Linux システムのタイムゾーンを変更するには、/etc/localtime ファイルを変更する必要があることがわかります。

Linuxコンテナのタイムゾーンを変更する

通常は、ホストの /etc/localtime ファイルをコンテナの /etc/localtime ファイルにコピーします。しかし、クエリによって、/etc/localtime ファイルは実際には単なるソフト リンクであることがわかりました。実際のファイルは次のとおりです: /usr/share/zoneinfo/Asia/Shanghai

docker cp /usr/share/zoneinfo/Asia/Shanghai テスト:/etc/localtime
TZ=Asia/Shanghai 環境変数をコンテナに挿入せずにコンテナにログインすると、コンテナのシステム時刻がローカル時刻とタイムゾーンを正しく取得していることがわかります。

TZ=Asia/Shanghai 環境変数が挿入されている場合、/etc/localtime ファイルが置き換えられても、タイムゾーンのみが変更され、時間は UTC 時間のままです。

Django環境に入り、時間を表示します

python manage.py シェル 
 
datetime から datetime をインポート 
日付時刻.now() 
# 出力 datetime.datetime(2021, 10, 8, 8, 43, 43, 754698) 

Linux のシステム時間は正常ですが、Django 環境の時間は依然として不正確で、UTC 時間のままです。この時点で、多くの人が少し頭がおかしくなり、settings.py の USE_TZ と TIME_ZONE の設定に問題があると考えるかもしれません。実際には、問題はここにはありません。その理由は、datetime ライブラリは /usr/share/zoneinfo/ ディレクトリで Asia/Shanghai ファイルを検索しますが、イメージにはこのディレクトリが含まれていないため、Django は引き続き UTC タイムゾーンを使用するためです。解決策は非常に簡単です。/usr/share/zoneinfo/Asia ディレクトリを作成し、ファイルをこのディレクトリにコピーします。

# コンテナ内(このディレクトリが存在しない場合) 
mkdir -p /usr/share/zoneinfo/アジア 
 
# コンテナ外 docker cp /usr/share/zoneinfo/Asia/Shanghai test:/usr/share/zoneinfo/Asia/Shanghai

次にコンテナにログインし、Django環境に入り時間を確認します。

python manage.py シェル 
 
datetime から datetime をインポート 
日付時刻.now() 
# 出力 datetime.datetime(2021, 10, 8, 16, 49, 32, 57) 

今回はタイミングがぴったりでした。

要約する

コンテナのタイムゾーンの問題については、コンテナ作成フェーズで/etc/localtimeをインストールして設定することをお勧めします。たとえば、Dockerfileに次のステートメントを追加します。

/usr/share/zoneinfo/Asia/Shanghai を追加します。 /usr/share/zoneinfo/Asia/Shanghai 
 
RUN ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime 

この方法では、コンテナを起動するときにタイムゾーンの問題を気にする必要はありません。コンテナが作成されている場合は、起動時にタイムゾーンファイルをマウントします。

docker run -d -v /etc/localtime:/etc/localtime -v /usr/share/zoneinfo/Asia/Shanghai:/usr/share/zoneinfo/Asia/Shanghai イメージ名 

この方法はもっと面倒です。私たちが現在直面しているもう 1 つの状況は、サービスがすでにオンラインになっていることです。時間的な問題があることがわかりました。2 つのファイルを手動でコンテナーにコピーし、コンテナーを再起動します。

docker cp /usr/share/zoneinfo/Asia/Shanghai テスト:/etc/localtime 
docker cp /usr/share/zoneinfo/Asia/Shanghai テスト:/usr/share/zoneinfo/Asia/Shanghai 
docker 再起動テスト 

これで、Docker コンテナに Django をデプロイする際のタイムゾーン問題についての記事は終了です。Django のタイムゾーンの Docker デプロイの詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • Docker で Django アプリケーションをデプロイする例
  • docker を使用して Django テクノロジー スタック プロジェクトをデプロイする方法
  • Docker を使用して Django プロジェクトをデプロイする方法の例
  • Django Docker コンテナのデプロイ Django-Docker ローカルデプロイ
  • Python Django アプリケーションを Docker 化する方法
  • Docker-compose を使用して Django アプリケーションをオフラインでデプロイする方法
  • Dockerを使用してDjango+MySQL8開発環境をデプロイする方法の詳細な説明

<<:  CSS 使用のヒントのまとめ

>>:  CSSはコンテンツの高さが足りない場合にフッターを自動的に下部に固定します

推薦する

MySQL の char、varchar、text フィールド タイプの違い

MySQL では、char、varchar、text の各タイプのフィールドはすべて文字タイプのデー...

フォーム OnSubmit と input type=image の使用の概要

ここに <input type="image"> がある場合、この画...

MySQL での coalesce() の使用に関するヒントのまとめ

序文最近、偶然 MySQL の coalesce を発見しました。ちょうど時間があったので、MySQ...

CSS3を使用してヘッダーアニメーション効果を作成する

Netease Kanyouxi公式サイト(http://kanyouxi.163.com/)(棚...

JavaScript は、シンプルな虫眼鏡の最も完全なコード分析を実装します (ES5)

この記事では、参考までに、シンプルな虫眼鏡を実装するためのJavaScriptの具体的なコードを紹介...

HTML+CSS3+JSで実装されたドロップダウンメニュー

成果を達成する html <div class="コンテナ"> &l...

HTML におけるいくつかの特殊属性タグの使用法の紹介

以下の属性はブラウザとの互換性があまりありません。 1.transform:rotate(45度) ...

この記事ではCSSの組み合わせセレクターの使い方を説明します

CSS 組み合わせセレクターには、単純なセレクターのさまざまな組み合わせが含まれます。 CSS3 に...

Vue の下部ナビゲーション バー TabBar を実装するための非常に詳細なチュートリアル

目次プロジェクト紹介:プロジェクトディレクトリ: TabBar 効果のプレビュー: TabBar 実...

MySQL タイムスタンプ比較クエリで遭遇する落とし穴と解決策

目次タイムスタンプ比較クエリで遭遇する落とし穴タイムスタンプクエリ範囲の問題タイムスタンプ比較クエリ...

MySQL 圧縮版 zip のインストールに関する問題の解決策

本日、MySQLの圧縮版をインストールする際に問題が発生しました。サービスが起動できず、2、3時間苦...

CSSは親コンテナのdivをimg画像で埋め、コンテナのサイズに適応します。

ページに複数の画像を導入すると、画像のサイズがばらつくことがあります。しかし、それらを一貫したサイズ...

Linux でのマルチスレッドにおけるフォークの紹介

目次質問:ケース(1)子スレッドを作成する前にフォークするケース(2)子スレッドを作成した後にフォー...

IE6/7 で絶対配置された要素が不可解に消えたりブロックされたりする問題を解決する方法

1. 絶対配置レイヤーの隣接フローティング レイヤーの幅が親レイヤーの幅と等しくなく、フロートがクリ...

Linux で TCP 接続の最大数をテストする方法

序文TCP サーバの最大同時接続数に関して、「ポート番号の上限が 65535 であるため、TCP サ...