Tempo e fuso horário do contêiner do Docker (não refletirá alterações)

Onde os contêineres Docker obtêm suas informações de tempo? Criei alguns contêineres a partir da imagem básica do ubuntu: trusty e, quando o executo e solicito 'data', recebo a hora UTC.

Por algum tempo, contornei isso fazendo o seguinte no meu Dockerfile:

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

No entanto, por algum motivo, isso parou de funcionar. Pesquisando on-line eu vi o abaixo sugerido:

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

Ambos os métodos definem corretamente o fuso horário!

$ cat /etc/timezoneAmerica/Los_Angeles$ dateTue Apr 14 23:46:51 UTC 2015

Alguém sabe o que dá?

O segredo aqui é que dpkg-reconfigure tzdata criar /etc/localtime como uma cópia, hardlink ou link simbólico (um link simbólico é preferido) para um arquivo em /usr/share/zoneinfo. Portanto, é possível fazer isso inteiramente do seu Dockerfile. Considerar:

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

E como bônus, o TZ também será definido corretamente no contêiner.

Isso também é independente da distribuição, por isso funciona com praticamente qualquer Linux.

Nota: Se você estiver usando uma imagem baseada em alpine, você deve instalar o tzdata primeiro. (veja este problema aqui)

Aspecto:

RUN apk add --no-cache tzdataENV TZ America/Los_Angeles

Normalmente, é suficiente definir uma variável de ambiente no contêiner docker, assim:

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

Claro que isso funcionaria também com docker-compose.

Você pode adicionar seus arquivos locais (/etc /Fuso horário e/etc / localtime) como volume em seu docker-container.

Atualize seu docker-compose.yml com as seguintes linhas.

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

Agora, o tempo do contêiner é o mesmo que no seu host

Montagem /etc/localtime na imagem, por isso está em sincronia com host -v é o mais popular.

Mas veja edição 12084:

não está correto porque não funciona quando o software requer o arquivo /etc/timezone para ser definido.
Dessa forma, você está usando leaves it como o valor padrão etc/UTC.

Eu determinei que, na verdade, não há uma maneira elegante e infalível de definir o fuso horário dentro de um contêiner docker.
Então, finalmente se estabeleceram nesta solução:

App dockerfile:

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

App entrypoint script:

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

Volume de dados /config dockerfile, localizado em um país ou região específica:

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

... não é elegante porque envolve 3 arquivos separados e recriação /etc/localtime em cada início do contêiner de tempo de execução. O que é um desperdício.

No entanto, ele funciona corretamente e consegue com sucesso a separação entre a imagem do aplicativo base e cada configuração localizada por país.
Em 3 linhas de código.

No ubuntu 16.04 imagem há bug. A solução foi

    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

Adicionando meus dois centavos aqui, porque tentei vários deles, mas nenhum funcionou em imagens baseadas em alpine.

No entanto, isso fez o truque:

ENV TZ=America/TorontoRUN apk updateRUN apk upgradeRUN apk add ca-certificates && update-ca-certificatesRUN apk add --update tzdataRUN rm -rf /var/cache/apk/*

[Fonte]

Na imagem básica alpine (exemplo use node: 10.16.0-alpine):

Dockerfile

FROM node:10.16.0-alpineENV TZ=America/Los_AngelesRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneWORKDIR /appCOPY package.json package-lock.json ./RUN npm i --productionCOPY . .CMD node index.js

Usando um contêiner Fedora (provavelmente funcionará com o ubuntu também):

A solução mais simples que encontrei foi usar o seguinte no docker-compose.yml

environment:   TZ: "${TZ:-America/Los_Angeles}"

Então em seu .arquivo env (que docker-compose lê automaticamente)

TZ=America/Los_Angeles

Isso permite que você coloque docker-compose.yml sob controle de versão e usar um personalizado .arquivo env que pode ser ignorado pelo git.

Você obtém um valor padrão para o contêiner e obtém personalização, o melhor dos dois mundos.

Para o Fedora, nenhuma outra mudança foi necessária, apenas funciona!

se você estiver usando a imagem do docker com base em ubuntu :

# Change the docker default timezone from UTC to SGTecho "Asia/Singapore" > /etc/timezonedpkg-reconfigure tzdatadate

Obrigado ao VonC pela informação e link para o problema. Isso parece uma bagunça tão complicada, então fiz alguns testes com minha própria ideia de como resolver isso e parece funcionar muito bem.

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

(siga as instruções para selecionar meu fuso horário)

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

Então eu atualizei meus Dockerfiles para refletir isso:

FROM chocko/ubuntu:local

Deve haver algo errado com isso, porque parece muito fácil de ser esquecido... Ou isso é aceitável?

Se você usar ‘Alpine, você precisa instalar tzdata’ primeiro, veja aqui How can I set the timezone please? · Issue #136 · gliderlabs/docker-alpine · GitHub

Para sua informação . . . Desejo definir o fuso horário do contêiner no tempo de execução do docker, não no tempo de compilação/dockerfile do docker. Usando` - V /etc/localtime:/etc/localtime:ro ’ (CentOS) tipo de trabalho. Dentro do contêiner, a data da linha de comando retorna a data no formato de fuso horário esperado. Mas jenkins em execução no contêiner acha que o fuso horário é UTC. Por quê? /etc / localtime é um link simbólico para …/usr/share/zoneinfo / UTC no recipiente construído. O conteúdo do arquivo UTC no contêiner agora é o novo fuso horário. Mas jenkins (e talvez outro software baseado em java) usa o nome do link simbólico que ainda é “UTC”. Procurando solução . . .

Precisa de 2 coisas, 1. quando o contêiner é criado, use um script init para definir o link simbólico /etc/localtime e/etc / Fuso horário e 2. para que o fuso horário jenkins seja retirado de duas opções java, essas opções precisam ser passadas para o script init que inicia o processo jenkins. por exemplo. " - Dorg.Apache.comuns.geleia.etiqueta.fmt.fuso horário = America / New_York-Douser.Fuso horário = America / New_York ". Desculpas, isso é específico do jenkins, mas espero que seja útil para alguns outros usuários do jenkins.