在Docker容器中部署Django的時區問題

2022-09-21 04:42:08 字數 3444 閱讀 6149

目錄

現在容器化部署已經非常成熟了,我們很多服務都會使用容器部署,更新恢復都非常方便,但是有乙個問題比較麻煩,就是時區處理,通常情況下,都採用注入 tz 環境變數來解決,但是實際這種處理方式在 django 中卻是不行的。

在www.cppcns.comdjango的配置檔案 settings.py 中,有兩個配置引數是跟時間與時區有關的,分別是time_zone和use_tz。我們期望著通過在 settings.py 中配置以後,django 就能正確地獲取本地時間,但是實際上卻事與願違,我們看一看這兩個設定有什麼作用。

如果 use_tz 設定為 true 時,django 會使用系統預設設定的時區,此時的 time_zone 的設定基本是無效的,也就是無論有沒有設定都不起作用。

如果 use_tz 設定為 false

如果是 windows 系統,則 time_zone 設定是沒用的,django會使用本機的時間

如果是其他系統,則會使用該時區的 utc 時間

例如設定 use_tz = false, time_zone = 『asia/shanghai', 則使用上海的 utc 時間。

到這一步,可能你會認為時間已經好了,但是實際上還沒有,我們還需要關注系統時區的設定。

現在我本地時間是:16:15,django 中設定為:use_tz = false, time_zone = 『asia/shanghai'

不注入 tz=asia/shanghai 環境變數

進入容器檢視容器時間和時區

系統時間顯示的是 utc 時區,時間為:08:15,剛好差 8 個小時

python manage.py shell

from datetime import datetime

datetime.now()

# 輸出 datetime.datetime(2021, 10, 8, 8, 24, 8, 289230)

from django.utils import timezone

timezone.get_current_timezonwww.cppcns.come_name()

# 輸出 'asia/shanghai'

注入環境變數 tz=asia/shanghai

進入容器檢視時間和時區

系統時間顯示的是 asia 時區,但是時間依然是 utc 時間,並沒有顯示真正的本地時間

進入 django 環境檢視時間和時區

python manage.py shell

from datetime import datetime

datetime.now()

# 輸出 datetime.datetime(2021, 10, 8, 8, 24, 8, 289230)

from django.utils import timezone

timezone.get_current_timezone_name()

# 輸出 'asia/shanghai'

可以看到,雖然時區變了,但是時間卻還是 utc 時間,無論是容器本身還是 django 中

通過在網上查詢,我們知道修改 linux 系統時區要修改 /etc/localtime 檔案

通常的做法是將宿主機的 /etc/localtime 檔案拷貝到容器的 /etc/localtime 檔案,但是我們通過查詢發現 /etc/localtime 檔案實際只是乙個軟連線,實際的檔案是:/usr/share/zoneinfo/asia/shanghai

docker cp /usr/share/zoneinfo/asia/shanghai test:/etc/localtime

在不給容器注入 tz=asia/shanghai 環境變數的情況下,我們登入容器發現,容器的系統時間已經正確獲取到本地時間和時區了

如果注入了 tz=asia/shanghai 環境變數,即使把 /etc/localtime 檔案替換了,也只是時區改變了,時間依然是 utc 時間

python manage.py shell

from datetime import 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 這個檔案,而我們的映象中不包含這個目錄,所以 d程式設計客棧jango 還是使用了 utc 時區。解決的辦法非常簡單:建立 /usr/share/zoneinfo/asia 目錄,拷貝檔案到這個目錄下就行了

# 在容器內(如不不存在這個目錄)

mkdir -p /usr/share/zoneinfo/asia

# 在容器外

docker cp /usr/share/zoneinfo/asia/shanghai test:/usr/share/zoneinfo/asia/shanghai

然後登入到容器內,進入 django 環境下檢視時間

python manage.py shell

from datetime import datetime

datetime.now()

#輸出 datetime.datetime(2021, 10, 8, 16, 49, 32, 57)

這下時間就完全正確了。

對於容器時區的問題,建議在容器程式設計客棧製作階段,安裝並設定好 /etc/localtime,例如在 dockerfile 中新增如下語句

gygpqlkzpzadd /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 imagename

這種方式就比較麻煩。還有一種情況就是我們現在碰到的,服務已經上線了,發現時間有問題,就手動拷貝一下那兩個檔案到容器中,然後重啟一下容器

docker cp /usr/share/zoneinfo/asia/shanghai test:/etc/localtime

docker cp /usr/share/zoneinfo/asia/shanghai test:/usr/share/zoneinfo/asia/shanghai

docker restart test

docker在獨立的容器中部署wordpress

yum install docker系統會自動安裝docker ce vi etc docker daemon.json 若檔案不存在則建立daemon.json 新增或修改以下字段 docker search mysql 從映象倉庫搜尋mysql映象 docker pull mysql 5.7.4...

在docker中部署gitlab

docker pull gitlab gitlab ce 12.5.4 ce.0 2.在docker建立容器,讓gitlab跑起來 docker run d publish 8443 443 publish 10080 80 publish 1022 22 name gitlab restart a...

在docker容器中部署網路程式進行通訊實驗

語言 python 1.實驗目的 這次試驗是在docker容器中部署網路程式,初定為寫乙個簡單的web伺服器並部署到docker上,然後讓其他主機訪問。開發語言使用python語言。2.實驗過程 1 搭建python開發環境 注意,實驗是要在docker容器中進行的,所以是在docker容器內安裝環...