Heure et fuseau horaire du conteneur Docker (ne reflétera pas les modifications)

Où les conteneurs Docker obtiennent - ils leurs informations temporelles? J'ai créé des conteneurs à partir de l'image de base ubuntu:trusty, et lorsque je l'exécute et que je demande 'date', j'obtiens l'heure UTC.

Pendant un certain temps, j'ai contourné cela en faisant ce qui suit dans mon Dockerfile:

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

Cependant, pour une raison quelconque, cela a cessé de fonctionner. En cherchant en ligne, j'ai vu les suggestions ci-dessous:

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

Cependant, ces deux méthodes définissent correctement le fuseau horaire!

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

Quelqu'un sait ce qui donne?

Le secret ici est que dpkg-reconfigure tzdata crée simplement /etc/localtime en tant que copie, lien dur ou lien symbolique (un lien symbolique est préféré) vers un fichier dans /usr/share/zoneinfo. Il est donc possible de le faire entièrement à partir de votre Dockerfile. Considérer:

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

Et en prime, TZ sera également réglé correctement dans le conteneur.

Ceci est également indépendant de la distribution, donc cela fonctionne avec à peu près n'importe quel Linux.

Remarque: si vous utilisez une image basée sur Alpine, vous devez installer le tzdata premier. (voir ce numéro ici)

Ressemble à ceci:

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

Habituellement, il suffit de définir une variable d'environnement dans le conteneur docker, comme ceci:

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

Bien sûr, cela fonctionnerait aussi avec docker-compose.

Vous pouvez ajouter vos fichiers locaux (/etc/timezone et /etc/localtime) en tant que volume dans votre conteneur docker.

Mettez à jour votre docker-compose.yml avec les lignes suivantes.

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

Maintenant, l'heure du conteneur est la même que sur votre hôte

Montage /etc/localtime dans l'image, il est donc synchronisé avec host -v est le plus populaire.

Mais voyez numéro 12084:

ce n'est pas correct car cela ne fonctionne pas lorsque le logiciel nécessite à la place le fichier /etc/timezone à régler.
De cette façon, vous l'utilisez comme valeur par défaut etc/UTC.

J'ai déterminé qu'il n'existe en fait aucun moyen élégant et infaillible de définir le fuseau horaire à l'intérieur d'un conteneur docker.
J'ai donc finalement opté pour cette solution:

Dockerfile d'application:

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

Script de point d'entrée d'application:

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

Volume de données /config dockerfile, localisé dans un pays ou une région spécifique:

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

... ce n'est pas élégant car impliquant 3 fichiers séparés, et recréant /etc/localtime à chaque démarrage du conteneur d'exécution. Ce qui est plutôt inutile.

Cependant, il fonctionne correctement et réussit à séparer l'image de l'application de base de chaque configuration localisée par pays.
En 3 lignes de code.

Dans l'image ubuntu 16.04, il y a un bug. La solution était

    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

J'ajoute mes deux cents ici, car j'en ai essayé plusieurs mais aucun n'a fonctionné sur des images basées sur alpine.

Cependant, cela a fait l'affaire:

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

[Source]

Dans l'image de base alpine (exemple d'utilisation du nœud: 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

Utilisation d'un conteneur Fedora (susceptible de fonctionner également avec ubuntu):

La solution la plus simple que j'ai trouvée était d'utiliser ce qui suit dans docker-compose.yml

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

Ensuite, dans votre .fichier env (que docker-compose lit automatiquement)

TZ=America/Los_Angeles

Cela vous permet de mettre docker-compose.yml sous contrôle de version et utilisez un personnalisé .fichier env qui peut être ignoré par git.

Vous obtenez une valeur par défaut pour le conteneur et vous obtenez une personnalisation, le meilleur des deux mondes.

Pour Fedora, aucun autre changement n'était nécessaire, cela fonctionne simplement!

si vous utilisez une image docker basée sur ubuntu :

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

Merci à VonC pour les informations et le lien vers le numéro. Cela semble être un gâchis tellement compliqué, alors j'ai fait des tests sur ma propre idée de la façon de résoudre ce problème et cela semble très bien fonctionner.

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

(suivez les invites pour sélectionner mon fuseau horaire)

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

Ensuite, j'ai mis à jour mes Dockerfiles pour refléter cela:

FROM chocko/ubuntu:local

Il doit y avoir quelque chose qui ne va pas avec cela parce que cela semble trop facile à négliger... Ou est-ce acceptable?

Si vous utilisez ‘Alpine’, vous devez d’abord installer ‘tzdata’, voir ici How can I set the timezone please? · Issue #136 · gliderlabs/docker-alpine · GitHub

Pour info . . . Je souhaite définir le fuseau horaire du conteneur au moment de l’exécution de docker et non au moment de la construction/du fichier docker. L’utilisation de - v / etc/localtime:/etc / localtime:ro (CentOS) fonctionne en quelque sorte. La ligne de commande date du conteneur renvoie la date au format de fuseau horaire attendu. MAIS jenkins fonctionnant dans un conteneur pense que le fuseau horaire est UTC. Pourquoi? /etc / localtime est un lien symbolique vers …/usr / share/zoneinfo / UTC dans le conteneur construit. Le contenu du fichier UTC dans le conteneur est maintenant le nouveau fuseau horaire. Mais jenkins (et peut-être d’autres logiciels basés sur Java) utilisent le nom du lien symbolique qui est toujours “UTC”. À la recherche d’une solution . . .

Besoin de 2 choses, 1. lorsque le conteneur est créé, utilisez un script d’initialisation pour définir le lien symbolique /etc/localtime et /etc / timezone et 2. pour que le fuseau horaire jenkins soit extrait de deux options Java, ces options doivent être transmises au script d’initialisation qui démarre le processus jenkins. par exemple " - Dorg.Apache.commun.gelée.balise.fmt.Fuseau horaire = America / New_York-Duser.fuseau horaire = America / New_York". Toutes mes excuses, c’est spécifique à jenkins mais j’espère utile pour d’autres utilisateurs de jenkins.