Where do Docker containers get their time information? I've created some containers from the basic ubuntu:trusty image, and when I run it and request 'date', I get UTC time.
For awhile I got around this by doing the following in my Dockerfile:
RUN sudo echo "America/Los_Angeles" > /etc/timezone
However, for some reason that stopped working. Searching online I saw the below suggested:
docker run -v /etc/timezone:/etc/timezone [image-name]
Both these methods correctly set the timezone though!
$ cat /etc/timezone
America/Los_Angeles
$ date
Tue Apr 14 23:46:51 UTC 2015
The secret here is that dpkg-reconfigure tzdata simply creates /etc/localtime as a copy, hardlink or symlink (a symlink is preferred) to a file in /usr/share/zoneinfo. So it is possible to do this entirely from your Dockerfile. Consider:
it is not correct because it does not work when the software requires instead the file /etc/timezone to be set.
That way you are using leaves it as the default value etc/UTC.
I have determined that actually there is no foolproof elegant way to set the time zone inside of a docker container.
So have finally settled on this solution:
App dockerfile:
# Relocate the timezone file
RUN 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/timezone
dpkg-reconfigure -f noninteractive tzdata
Data volume /config dockerfile, localized to a specific country or region:
# Set the time zone
RUN echo "Europe/London" > /config/etc/timezone
... it is not elegant because involving 3 separate files, and re-creating /etc/localtime on every runtime container start. Which is rather wasteful.
However it does work properly, and successfully achieve separation between the base app image, and each per-country localized configuration.
In 3 lines of code.
Adding my two cents here, because I've tried several of these but none worked on alpine-based images.
However, this did the trick:
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/*
Thanks to VonC for the information and link to the issue. This seems like such a convoluted mess, so I did some testing on my own idea of how to solve this and it seems to work great.
>docker run -it ubuntu:trusty /bin/bash
#dpkg-reconfigure tzdata
(follow prompts to select my timezone)
>docker commit [container-id] chocko/ubuntu:local
Then I updated my Dockerfiles to reflect this:
FROM chocko/ubuntu:local
There must be something wrong with this because it seems too easy to be overlooked... Or is this acceptable?
FYI . . . I wish to set the timezone of container at docker run time not at docker build/dockerfile time. Using -v /etc/localtime:/etc/localtime:ro (CentOS) sort of works. Inside container command-line date returns date in the expected timezone format. BUT jenkins running in container thinks timezone is UTC. Why? /etc/localtime is a symlink to …/usr/share/zoneinfo/UTC in built container. The content of the UTC file in container is now the new timezone. But jenkins (and perhaps other java based software) use the name of the symlink which is still “UTC”. Searching for solution . . .
Need 2 things, 1. when container is created use an init script to set /etc/localtime symlink and /etc/timezone and 2. for jenkins timezone is taken from two java options, these options need to be passed to the init script which starts the jenkins process. e.g. " -Dorg.apache.commons.jelly.tags.fmt.timeZone=America/New_York -Duser.timezone=America/New_York ". Apologies, this is jenkins specific but hopefully useful for some other jenkins users.