Ora e fuso orario del contenitore Docker (non rifletterà le modifiche)


136

Dove ottengono le informazioni sul tempo dai container Docker? Ho creato alcuni contenitori dall'ubuntu di base: immagine affidabile, e quando lo eseguo e richiedo 'data', ottengo l'ora UTC.

Per un po 'mi sono aggirato nel modo seguente nel mio Dockerfile:

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

Tuttavia, per qualche motivo che ha smesso di funzionare. Cercando online ho visto quanto segue suggerito:

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

Entrambi questi metodi impostano correttamente il fuso orario però!

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

Qualcuno sa cosa dà?


3
Se lo usi Alpine, devi tzdataprima installarlo , vedi qui github.com/gliderlabs/docker-alpine/issues/136
Belter

1
PER TUA INFORMAZIONE . . . Desidero impostare il fuso orario del contenitore al momento dell'esecuzione della finestra mobile non al momento della creazione della finestra mobile / del file docker. Utilizzo di -v /etc/localtime:/etc/localtime:ro(CentOS) specie di opere. La data della riga di comando all'interno del contenitore restituisce la data nel formato del fuso orario previsto. MA jenkins in esecuzione in un container pensa che il fuso orario sia UTC. Perché? / etc / localtime è un link simbolico a ../usr/share/zoneinfo/UTC nel contenitore incorporato. Il contenuto del file UTC nel contenitore è ora il nuovo fuso orario. Ma jenkins (e forse altri software basati su Java) usano il nome del collegamento simbolico che è ancora "UTC". Alla ricerca di una soluzione. . .
Gaoithe

1
Sono necessarie 2 cose, 1. quando viene creato il contenitore, utilizzare uno script init per impostare / etc / localtime symlink e / etc / timezone e 2. per jenkins il fuso orario viene preso da due opzioni java, queste opzioni devono essere passate allo script init che avvia il processo di jenkins. ad es. "-Dorg.apache.commons.jelly.tags.fmt.timeZone = America / New_York -Duser.timezone = America / New_York". Ci scusiamo, questo è jenkins specifico ma si spera utile per alcuni altri utenti di jenkins.
Gaoithe

Risposte:


209

Il segreto qui è che dpkg-reconfigure tzdatacrea semplicemente /etc/localtimeuna copia, un hardlink o un symlink (è preferito un symlink) in un file /usr/share/zoneinfo. Quindi è possibile farlo interamente dal tuo Dockerfile. Tener conto di:

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

E come bonus, anche TZ verrà impostato correttamente nel container.

Anche questo è indipendente dalla distribuzione, quindi funziona praticamente con qualsiasi Linux.

Nota: se si utilizza un'immagine di tipo alpino, è necessario installare la tzdataprima. (vedi questo problema qui )

Somiglia a questo:

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


5
Con Ubuntu: 16.04 (e forse altre versioni) è necessario disporre del tzdatapacchetto installato per farlo funzionare.
Opsse,

5
Sono l'unico a pensare che non sia molto intelligente codificare un fuso orario nel Dockerfile?
Wolfgang,

1
@Wolfgang Questo è un esempio. Puoi fornirlo in qualsiasi altro modo in cui normalmente forniresti variabili d'ambiente, come la riga di comando, docker-compose.yml, ecc.
Michael Hampton

Ho notato che, almeno per le immagini basate su Alpine, bastava solo impostare la TZvariabile. Non ho dovuto impostare i collegamenti simbolici o altro.
code_dredd,

58

Di solito è sufficiente impostare una variabile d'ambiente nel contenitore finestra mobile, in questo modo:

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

Naturalmente questo funzionerebbe anche con docker-compose.


2
Questo sembra essere il modo più elegante. Fai attenzione che alcune immagini di base, come ubuntu:16.04, non abbiano il tzdatapacchetto che dovrebbe essere aggiunto in Dockerfile.
Julien Fastré,

1
+1 - Sono d'accordo con Julien; questo sembra essere l'approccio più elegante per impostare i fusi orari in fase di esecuzione. Funziona bene con CentOS. L'immagine alpina richiede l'installazione del pacchetto 'tzdata', che è preferito rispetto alle configurazioni di codifica in fase di compilazione a meno che non sia possibile tollerare il payload aggiuntivo di 3 MB di immagine :)
Frelling

Questo sembra buono ma sembra non funzionare per me (con CentOS 7.5.1804 e tzdata-2018e-3.el7.noarch)? faccia triste
gaoithe

22

Montare /etc/localtimenell'immagine, quindi è in sincronia con host -vil più popolare.

Ma vedi il numero 12084 :

non è corretto perché non funziona quando il software richiede invece /etc/timezonedi impostare il file .
In questo modo lo stai usando come valore predefinito etc/UTC.

Ho determinato che in realtà non esiste un modo elegante infallibile per impostare il fuso orario all'interno di un contenitore docker.
Quindi ho finalmente deciso su questa soluzione:

File docker app:

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

Script di ingresso dell'app:

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

/configFile Docker del volume di dati , localizzato in un Paese o una regione specifici:

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

... non è elegante perché coinvolge 3 file separati e ricreando /etc/localtimeogni avvio del contenitore di runtime. Il che è piuttosto dispendioso.

Tuttavia funziona correttamente e raggiunge con successo la separazione tra l'immagine dell'app di base e ciascuna configurazione localizzata per Paese.
In 3 righe di codice.


1
Per me era: RUN echo "Europe/London" > /etc/timezone
jpmottin,

@jpmottin Quindi un po 'come in serverfault.com/a/856593/783 allora?
VonC,

18

Puoi aggiungere i tuoi file locali (/ etc / timezone e / etc / localtime) come volume nel tuo contenitore docker.

Aggiorna il tuo docker-compose.ymlcon le seguenti righe.

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

Ora il tempo del contenitore è lo stesso del tuo host


Se l'host di distribuzione su CentOS immette il comando echo "Europe/Paris" > /etc/timezoneprima di riavviare il contenitore.
CrazyMax,

Funziona su host MacOS?
Redsandro,

Non funziona in MAC
Marcello de Sales

Questo funzionava su MacOS ma l'ho provato di nuovo dopo tanto tempo e ottengo quanto segue. Non sono sicuro che High Sierra o una modifica della finestra mobile abbiano causato questo: "finestra mobile: risposta di errore dal demone: montaggi negati: il percorso / etc / localtime non è condiviso da OS X e non è noto a Docker. Puoi configurare percorsi condivisi da Docker - > Preferenze ... -> Condivisione file. Per ulteriori informazioni, consultare docs.docker.com/docker-for-mac/osxfs/#namespaces ".
gae123

1
Questo corromperà il tuo db zoneinfo come / etc / localtime è un link simbolico (quindi è probabile che / usr / share / zoneinfo / Some / Thing venga montato come / usr / share / zoneinfo / UTC all'interno del contenitore). Per non parlare del fatto che avresti mescolato il file db dall'host con quello nel contenitore.
ionelmc,

12

Nell'immagine di Ubuntu 16.04 c'è un bug. La soluzione era

    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

1
Scherzi a parte ... questa è l'unica soluzione che ha funzionato!
Gerrat,

1
Anche dovuto farlo - sembra che tzdata non sia più in alcune distro per impostazione predefinita.
Peter,

4

se si sta utilizzando l'immagine docker in base a ubuntu:

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

3

Grazie a VonC per le informazioni e il collegamento al problema. Sembra un casino così contorto, quindi ho fatto alcuni test sulla mia idea di come risolverlo e sembra funzionare alla grande.

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

(segui le istruzioni per selezionare il mio fuso orario)

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

Quindi ho aggiornato i miei file Docker per riflettere questo:

FROM chocko/ubuntu:local

Deve esserci qualcosa di sbagliato in questo perché sembra troppo facile da trascurare ... O è accettabile?


Questo è anche quello che ho provato, ma il fuso orario si ripristina ancora dopo exitil contenitore. Questo è su Debian.
Mike Chamberlain,

@MikeChamberlain ti è capitato di provare la risposta accettata da Michael Hampton sopra? Non l'ho implementato da solo, ma penso che sia la strada da percorrere considerando i voti che ha ricevuto.
Chockomonkey,

2

Aggiungendo qui i miei due centesimi, perché ho provato molti di questi, ma nessuno ha funzionato su immagini di tipo alpino.

Tuttavia, questo ha funzionato:

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/*

[ Fonte ]


1

Un modo più generico per impostare il fuso orario negli docker runargomenti:

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

O per il riutilizzo:

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

...
-e TZ=`GET_TZ`

non aiuta se l'immagine di base è alpina (5 MB) su cui non è installato il "tzdata"
max4ever
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.