Откуда контейнеры 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`