Docker Container time & timezone (will not reflect changes)
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
Anyone know what gives?
Solution 1:
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:
ENV TZ=America/Los_Angeles
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
And as a bonus, TZ will be set correctly in the container as well.
This is also distribution-agnostic, so it works with pretty much any Linux.
Note: if you are using an alpine based image you have to install the tzdata
first. (see this issue here)
Looks like this:
RUN apk add --no-cache tzdata
ENV TZ America/Los_Angeles
Solution 2:
Usually it is sufficient to set an environment variable in the docker container, like so:
docker run -e TZ=Europe/Amsterdam debian:jessie date
Of course this would work also with docker-compose
.
Solution 3:
You can add your local files (/etc/timezone and /etc/localtime) as volume in your docker-container.
Update your docker-compose.yml
with the following lines.
volumes:
- "/etc/timezone:/etc/timezone:ro"
- "/etc/localtime:/etc/localtime:ro"
Now the container time is the same as on your host
Solution 4:
Mounting /etc/localtime
in the image, so it is in sync with host -v
is the most popular one.
But see issue 12084:
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 valueetc/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.