By default, Docker and Container uses UTC timezone. When container engines like Podman, Docker or CRI-O run containers, they pull down the specified OCI image from a container registry. The container image is usually built with a hardcoded link from /etc/localtime to one timezone. Once the image is pulled, the container engine just launches the container based on the hardcoded time zone. This means that your container running in London could be reporting that it is running in New York or Singapore, depending on where the image was built. Depending on your application and sometimes to meet certain audit requirements, it might be necessary for you to control the timezone in the containers.
Unfortunately, the option to control timezone in the containers / pods can vary, depending upon your container engine, the type of the OS in the container image, the versions of the container engines and platform used to run container engines. We’ll discuss some of these in this post.
With Docker Engine
The timezone of a container can be set using an environment variable in the docker container when it is created. For example:
$ docker run ubuntu:latest date Sat Feb 27 15:58:32 UTC 2021 $ docker run -e TZ=Asia/Kolkata ubuntu:latest date Sat Feb 27 15:58:40 Asia 2021
However, above works only if the image is fedora based. For alpine based images, it does not work:
$ docker run alpine:latest date Sat Feb 27 16:00:05 UTC 2021 $ docker run -e TZ=Asia/Kolkata alpine:latest date Sat Feb 27 16:00:26 UTC 2021
Do note that, docker engine uses containerd runtime these days, instead of docker runtime. So what said above is true for container engines using containerd.
We can also control container timezone using the Dockerfile. For this, we first need to install tzdata package and then specify timezone setting using the environmental variable:
FROM ubuntu:16.04 # tzdata for timzone RUN apt-get update -y RUN apt-get install -y tzdata # timezone env with default ENV TZ Asia/India
Lets build docker image and run it:
# build docker image $ docker build -t ubuntu_modified_tz:20210221 . # run docker container $ docker run ubuntu_modified_tz:20210221 date Sat Feb 27 16:58:17 Asia 2021
With Docker Compose
We can control timezone in the container, by setting TZ environment variable as part of docker-compose:
version: "3.9" services: ubuntu: image: ubuntu:latest container_name: ubuntu_container environment: - TZ=Asia/Kolkata
Again, it depends if the underlying OS has tzdata package installed or not, to support this variable. Also, instead of making it a part of docker-compose, you can supply it at runtime with docker-compose.
With Storage Data Volumes
The directory /usr/share/zoneinfo in Docker contains the container time zones available. The desired time zone from this folder can be copied to /etc/localtime file, to set as default time.
This time zone files of the host machine can be set in Docker volume and shared among the containers by configuring it in the Dockerfile as below:
volumes: - "/etc/timezone:/etc/timezone:ro" - "/etc/localtime:/etc/localtime:ro"
The containers created out of this Dockerfile will have the same timezone as the host OS (as set in /etc/localtime file).
This method can also be used to set timezone when using docker compose. However as we have noted above, this might not work for all cases.
With Kubernetes Pods
Again, we have to rely here on setting up of the TZ variable:
spec: containers: - name: demo image: docker.io/ubuntu:latest imagePullPolicy: Always env: - name: TZ value: Asia/Kolkata
If we are using deployments, we can mention environment variable as part of container spec:
apiVersion: apps/v1 kind: Deployment metadata: name: demo spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: demo image: docker.io/ubuntu:latest imagePullPolicy: Always env: - name: TZ value: Asia/Kolkata dnsPolicy: ClusterFirst restartPolicy: Always terminationGracePeriodSeconds: 0
If above does not work, you may also choose to use host volumes to map /etc/localtime file with the pods/deployments.