Назад | Перейти на главную страницу

Время и часовой пояс Docker Container (не будут отражать изменения)

Откуда контейнеры Docker получают информацию о времени? Я создал несколько контейнеров из базового образа ubuntu: trusty, и когда я запускаю его и запрашиваю дату, я получаю время в формате UTC.

Некоторое время я обходил это, выполнив следующее в моем Dockerfile:

RUN sudo echo "America/Los_Angeles" > /etc/timezone

Однако по какой-то причине это перестало работать. Поискав в Интернете, я увидел предложенное ниже:

docker run -v /etc/timezone:/etc/timezone [image-name]

Оба этих метода правильно устанавливают часовой пояс!

$ cat /etc/timezone
America/Los_Angeles
$ date
Tue Apr 14 23:46:51 UTC 2015

Кто-нибудь знает, что дает?

Секрет в том, что dpkg-reconfigure tzdata просто создает /etc/localtime как копия, жесткая ссылка или символическая ссылка (предпочтительно символическая ссылка) на файл в /usr/share/zoneinfo. Таким образом, это можно сделать полностью из вашего Dockerfile. Рассматривать:

ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

И в качестве бонуса, в контейнере также будет правильно выставлена ​​TZ.

Он также не зависит от дистрибутива, поэтому работает практически с любым Linux.

Примечание: если вы используете образ на основе alpine, вам необходимо установить tzdata первый. (см. этот выпуск Вот)

Выглядит так:

RUN apk add --no-cache tzdata
ENV TZ America/Los_Angeles

Обычно достаточно установить переменную окружения в контейнере докера, например:

docker run -e TZ=Europe/Amsterdam debian:jessie date

Конечно, это также будет работать с docker-compose.

Вы можете добавить свои локальные файлы (/ etc / timezone и / etc / localtime) в качестве тома в свой docker-контейнер.

Обновите свой docker-compose.yml со следующими строками.

volumes:
    - "/etc/timezone:/etc/timezone:ro"
    - "/etc/localtime:/etc/localtime:ro"

Теперь время контейнера такое же, как на вашем хосте

Монтаж /etc/localtime на изображении, поэтому он синхронизирован с host -v самый популярный.

Но посмотри Выпуск 12084:

это неправильно, потому что это не работает, когда программное обеспечение требует вместо этого файла /etc/timezone быть установленным.
Таким образом, вы используете его как значение по умолчанию etc/UTC.

Я определил, что на самом деле не существует надежного элегантного способа установить часовой пояс внутри контейнера докеров.
Итак, наконец, остановились на этом решении:

Файл докеров приложения:

# Relocate the timezone file
RUN mkdir -p /config/etc && mv /etc/timezone /config/etc/ && ln -s /config/etc/timezone /etc/

Скрипт точки входа в приложение:

# Set timezone as specified in /config/etc/timezone
dpkg-reconfigure -f noninteractive tzdata

Объем данных /config dockerfile, локализованный для конкретной страны или региона:

# Set the time zone
RUN echo "Europe/London" > /config/etc/timezone

... это не элегантно, потому что задействует 3 отдельных файла и воссоздает /etc/localtime при каждом запуске контейнера времени выполнения. Что довольно расточительно.

Однако он работает правильно и успешно обеспечивает разделение между базовым образом приложения и каждой локализованной конфигурацией для каждой страны.
В 3 строчках кода.

В образе ubuntu 16.04 есть ошибка. Решение было

    ENV TZ 'Europe/Tallinn'
    RUN echo $TZ > /etc/timezone && \
    apt-get update && apt-get install -y tzdata && \
    rm /etc/localtime && \
    ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
    dpkg-reconfigure -f noninteractive tzdata && \
    apt-get clean

если вы используете образ докера на основе ubuntu :

# Change the docker default timezone from UTC to SGT
echo "Asia/Singapore" > /etc/timezone
dpkg-reconfigure tzdata
date

Добавляю сюда свои два цента, потому что я пробовал несколько из них, но ни один из них не работал с альпийскими изображениями.

Однако это сработало:

ENV TZ=America/Toronto
RUN apk update
RUN apk upgrade
RUN apk add ca-certificates && update-ca-certificates
RUN apk add --update tzdata
RUN rm -rf /var/cache/apk/*

[Источник]

Спасибо VonC за информацию и ссылку на проблему. Это кажется таким запутанным беспорядком, поэтому я провел некоторое тестирование собственной идеи, как решить эту проблему, и, похоже, она отлично работает.

>docker run -it ubuntu:trusty /bin/bash
#dpkg-reconfigure tzdata

(следуйте инструкциям, чтобы выбрать мой часовой пояс)

>docker commit [container-id] chocko/ubuntu:local

Затем я обновил свои файлы Docker, чтобы отразить это:

FROM chocko/ubuntu:local

С этим должно быть что-то не так, потому что это слишком легко, чтобы не заметить ... Или это приемлемо?

В базовом образе alpine (пример использования узла: 10.16.0-alpine):

Dockerfile

FROM node:10.16.0-alpine

ENV TZ=America/Los_Angeles

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

WORKDIR /app

COPY package.json package-lock.json ./

RUN npm i --production

COPY . .

CMD node index.js

Более общий способ установить часовой пояс в docker run аргументы:

-e TZ=`ls -la /etc/localtime | cut -d/ -f8-9`

Или для повторного использования:

function GET_TZ () {
    ls -la /etc/localtime | cut -d/ -f8-9
}

...
-e TZ=`GET_TZ`