263 votos

Contenedor de Docker tiempo y zona horaria (no reflejará cambios)

¿Dónde obtienen su información de tiempo los contenedores de Docker? He creado algunos contenedores a partir de la imagen básica de ubuntu:trusty, y cuando lo ejecuto y solicito 'date', obtengo la hora UTC.

Por un tiempo, solucioné esto haciendo lo siguiente en mi Dockerfile:

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

Sin embargo, por alguna razón eso dejó de funcionar. Buscando en línea vi lo siguiente sugerido:

docker run -v /etc/timezone:/etc/timezone [nombre-de-la-imagen]

¡Ambos métodos establecen correctamente la zona horaria aunque!

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

¿Alguien sabe qué pasa?

5 votos

Si usas Alpine, primero necesitas instalar tzdata, ve aquí github.com/gliderlabs/docker-alpine/issues/136

2 votos

Para información . . . Me gustaría establecer la zona horaria del contenedor en tiempo de ejecución de docker y no en el tiempo de construcción del docker/dockerfile. Usar -v /etc/localtime:/etc/localtime:ro (CentOS) funciona en parte. Dentro del contenedor, el comando de línea de fecha devuelve la fecha en el formato de zona horaria esperado. PERO jenkins en ejecución dentro del contenedor piensa que la zona horaria es UTC. ¿Por qué? /etc/localtime es un enlace simbólico a ../usr/share/zoneinfo/UTC en el contenedor construido. El contenido del archivo UTC en el contenedor es ahora la nueva zona horaria. Pero jenkins (y quizás otro software basado en Java) utilizan el nombre del enlace simbólico que aún es "UTC". Buscando solución . . .

1 votos

Necesito 2 cosas, 1. cuando se crea el contenedor, utilizar un script de inicio para configurar el enlace simbólico /etc/localtime y /etc/timezone y 2. para jenkins, la zona horaria se obtiene de dos opciones de Java, estas opciones deben pasarse al script de inicio que inicia el proceso de jenkins. por ejemplo, " -Dorg.apache.commons.jelly.tags.fmt.timeZone=America/New_Yor‌​k -Duser.timezone=America/New_York ". Disculpas, esto es específico de jenkins pero espero que sea útil para otros usuarios de jenkins.

370voto

Michael Hampton Puntos 88271

El secreto aquí es que dpkg-reconfigure tzdata simplemente crea /etc/localtime como una copia, hardlink o symlink (se prefiere un symlink) a un archivo en /usr/share/zoneinfo. Por lo tanto, es posible hacer esto completamente desde tu Dockerfile. Considera:

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

Y como bono adicional, TZ se establecerá correctamente en el contenedor también.

Esto también es independiente de la distribución, por lo que funciona con prácticamente cualquier Linux.

Nota: si estás utilizando una imagen basada en alpine, primero debes instalar tzdata. (ver este problema aquí)

Se vería así:

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

42 votos

12 votos

Con Ubuntu: 16.04 (y tal vez otras versiones) necesitas tener el paquete tzdata instalado para que esto funcione.

13 votos

¿Soy el único que piensa que no es muy inteligente codificar un huso horario en el Dockerfile?

119voto

joe Puntos 22

Por lo general, es suficiente establecer una variable de entorno en el contenedor de Docker, de la siguiente manera:

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

Por supuesto, esto también funcionaría con docker-compose.

9 votos

Esta parece ser la forma más elegante. Asegúrate de que algunas imágenes base, como ubuntu:16.04, no tengan el paquete tzdata que debe agregarse en el Dockerfile.

2 votos

+1 - Estoy de acuerdo con Julien; esta parece ser la forma más elegante de establecer zonas horarias en tiempo de ejecución. Esto funciona bien con CentOS. La imagen de Alpine requiere la instalación del paquete 'tzdata', lo cual se prefiere por encima de codificar configuraciones en tiempo de compilación a menos que no se pueda tolerar la carga adicional de 3MB en la imagen :)

0 votos

Esto parece bueno pero parece que no funciona para mí (con CentOS 7.5.1804 y tzdata-2018e-3.el7.noarch)

40voto

JohnK Puntos 11

Puedes agregar tus archivos locales (/etc/timezone y /etc/localtime) como volumen en tu contenedor de Docker.

Actualiza tu docker-compose.yml con las siguientes líneas.

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

Ahora el tiempo del contenedor es el mismo que en tu host

1 votos

Si estás en un host con distribución CentOS, ingresa el comando echo "Europe/Paris" > /etc/timezone antes de reiniciar el contenedor.

1 votos

¿Funciona esto en un host MacOS?

3 votos

No FUNCIONA en MAC

23voto

Audrius Puntos 121

Montar /etc/localtime en la imagen, para que esté sincronizado con host -v es la más popular.

Pero ver problema 12084:

no es correcto porque no funciona cuando el software requiere en su lugar que el archivo /etc/timezone sea configurado.
De esa manera, se queda con el valor predeterminado etc/UTC.

He determinado que en realidad no hay una forma elegante infalible de configurar la zona horaria dentro de un contenedor de Docker.
Así que finalmente me he decidido por esta solución:

Dockerfile de la aplicación:

# Trasladar el archivo de zona horaria
RUN mkdir -p /config/etc && mv /etc/timezone /config/etc/ && ln -s /config/etc/timezone /etc/

Script de entrada de la aplicación:

# Establecer la zona horaria como se especifica en /config/etc/timezone
dpkg-reconfigure -f noninteractive tzdata

Volumen de datos /config en el Dockerfile, localizado en un país o región específicos:

# Establecer la zona horaria
RUN echo "Europe/London" > /config/etc/timezone

... no es elegante porque involucra 3 archivos separados, y recrea /etc/localtime en cada inicio de contenedor en tiempo de ejecución. Lo cual es bastante ineficiente.

Sin embargo, funciona correctamente y logra separación entre la imagen base de la aplicación y cada configuración localizada por país.
En 3 líneas de código.

2 votos

Para mí, fue: RUN echo "Europe/London" > /etc/timezone

0 votos

@jpmottin ¿Entonces algo así como serverfault.com/a/856593/783 ?

18voto

Kiran Mohan Puntos 1029

En la imagen de ubuntu 16.04 hay un bug. La solución fue

    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

2 votos

En serio...¡esta es la única solución que funcionó!

1 votos

También tuve que hacer esto - parece que tzdata ya no está incluido por defecto en algunas distribuciones.

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X