Adjust time and timezone on Linux
Before covering the Docker part of this guide, it is necessary to remember how to set up the time and timezone of Linux servers, because it’s the same methods that we are going to use afterwards to synchronize our containers, which are based on Linux.
First thing first, let’s take a look at the current time:
$ date Tue Nov 17 15:26:20 CET 2020
There are two important things here:
- The timezone, here it’s CET for Central European Time, in short it’s Paris time.
- The hour itself, which can be well synchronized or not. You can compare it for example with this one.
In order to change the timezone on Linux, it’s pretty simple. You just need to run this command and follow the given instructions:
To synchronize the clock with the right time, we use a service called NTP, for Network Time Protocol. Let’s make sure that it’s properly installed and enabled in
Adapte these commands to your OS, here for Debian 10:
apt install ntp systemctl enable ntp systemctl start ntp
It’s not necessary to install
ntpin Docker containers, as their clock is based on the host one.
Well, now that we covered the bases, we need to make sure that our Docker containers have their clock properly synchronized, are on the right timezone, and stop having interaction issues due to their datetime.
Use host machine configuration
This is the simplest solution for setting the time of your containers: using the time and time zone of the host machine, the one that hosts the Docker service.
On the other hand, this solution only works if you have control of the host, and it is not applicable if you send your containers into any cloud solution.
To do this, we will mount two volumes in read-only mode on the configuration files of the host clock in our containers.
docker run command, we add two volumes:
docker run -d \ -v /etc/timezone:/etc/timezone:ro \ -v /etc/localtime:/etc/localtime:ro \ [...]
Or with a
services: service_name: volumes: - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro"
Set the time zone of the containers
If the previous method cannot be applied, either because you don’t have control over the host, or if it is necessary to have different time zones between different containers, then you need to be able to set the timezone directly in the Docker image.
First, for Alpine Linux, package
tzdata is not installed by default, so it’s necessary to add it manually in your Dockerfile:
RUN apk add --no-cache tzdata
To change the time zone of our Linux containers, instead of using
dpkg-reconfigure which is interactive, we will use a little subtlety and do the manipulation manually in our Dockerfile.
What this command does is on the one hand to update the
/etc/timezone file with the correct time zone, but also to create a copy of the binary associated with the timezone in
/etc/localtime. So let’s do this:
FROM alpine ENV TZ=Europe/Paris RUN apk add --no-cache tzdata RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
This method works everywhere, and allows you to directly define the
TZ environment variable detailed in the next section.
You can test your file this very easily with the command :
docker build -t tzalpine . && docker run -it --rm tzalpine $ date # the date must have the right time zone here
The OS is now up to date inside the containers, whatever the configuration or environment. All that’s left to do is to make sure that the different software takes the time zone into account.
TZ environment variable
A good part of modern programming languages and/or frameworks rely on the same environment variable:
TZ. This is the case for example to set the time in Python and NodeJS.
By defining it, and together with the operating system one, you should cover a good majority of use cases.
Beware however, this variable can usually be overloaded, if it is the choice of the developers. In these cases, there is usually an option available in the configuration of the tool you are using, or sometimes in its UI.
You just have to set it when you launch your container :
docker run -d \ -e TZ=Europe/Paris \ [...]
services: service_name: environment: - TZ=Europe/Paris
Obviously, PHP uses a different way and does not take into account the
TZ environment variable.
To set the time in PHP, you need to set the value of the
date.timezone parameter in the
[Date] ; Be careful to remove the semicolon, which means it's a comment. date.timezone = Europe/Paris
There, we should have covered the whole subject. I’ve updated most of my containers to take these changes into account, and everything seems to be running smoothly.
If you ever encounter cases where the manipulations described in this article are not sufficient, don’t hesitate to let me know - I will update this guide.
2020-12-08 11:16 +0000