在 Docker build 時一併設定時區 (Dockerfile / run / compose)

前言

  • 最近在包版時,發現定時抓資料的時間沒有正常啟動,最後才知道原來時區預設套用了 UTC!

  • 本文介紹如何在 Dockerfile 以及 Docker compose 中設定時區。




Dockerfile / docker run

環境變數

在 build container 時,可以用 ENV 來設定容器的時區:

1
2
TZ=Asia/Taipei
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
  • Asia/Taipei 為時區名稱,可以根據實際需修改。

或是在 docker run 時用 -e 帶入環境變數:

1
docker run -e TZ=Asia/Taipei ${your_image}

把主機的時區設定 mount 進 container

第三種方式是將主機的 /etc/localtime mount 入 container 中:

1
docker run -v /etc/localtime:/etc/localtime:ro ${your_image}
  • 其中,ro 表示以 read-only 模式 mount,防止在容器中修改到主機的時區。



Docker compose

與前面邏輯相同,一個方法是使用環境變數、另一個方式是 mount,各自有對應的 docker compose 寫法。


環境變數

  • 在 compose yaml 中指定環境變數:
1
2
3
4
5
6
version: '3.9'
services:
  web:
    image: ${your_image}
    environment:
      - TZ=Asia/Taipei

Mount 主機的時區

  • mount 主機的時區 - /etc/timezone
1
2
3
4
5
6
7
version: '3.9'
services:
  web:
    image: ${your_image}
    volumes:
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro

驗證

  • 用 docker exec 進入 running 中的 container,下 date 確認即可:
1
2
3
docker exec -it ${container_name} /bin/bash
# 進入 container 後
date

當然,單純確認一次、沒有其他後續工作需要處理的話就不用 bash,直接下 date

1
docker exec -it ${container_name} date


Note

  • 如果容器中的程式需要 access 主機的時間,就必須使用 mount 的方式以維持同步。



REF


主題 StackJimmy 設計