How to Handle Timezones in Docker Containers – CloudSavvy IT


    Illustration showing the Docker logo

    Timezones are a common source of confusion when containerizing an application. Will your cron tasks run at the right time? Docker containers don’t inherit the host’s timezone, so you can run into unexpected scheduling issues that wreak havoc with your application.

    Here’s the date command running natively on an Ubuntu 20.04 host in the British Summer Time timezone:

    And here’s the same command in a container based on an unmodified ubuntu:20.04 image:

    The container is using the UTC timezone, creating a one hour difference between the two times.

    How Do Linux Timezones Work?

    Most Linux distributions use the tzdata package to provide timezone information. When tzdata is installed, you can inspect the current timezone by reading the /etc/timezone file:

    You’ll also have an /etc/localtime file. This is a symlink to the correct timezone database for the selected location:

    If you change the timezone, using dpkg-reconfigure tzdata, the /etc/localtime symlink gets updated to point to the new database. The output of commands like date will be adjusted to include the active timezone’s offset.

    The Problem With Containers

    The challenge with containers derives from setting the timezone in the first place. If you think back to when you setup your host, you’d have needed to set the timezone as part of the operating system installation. When you run a new container, it starts immediately though, without any “installation” stage. There’s no opportunity to select an appropriate timezone.

    Theoretically, container runtimes could offer automatic inheritance of the host’s timezone. This doesn’t happen as it might lead to unexpected results when deploying to remote environments. It would be easy to overlook that your cron schedule works on your local machine but executes unexpectedly in a managed Kubernetes cluster using UTC time.

    Container images ship with a baked-in timezone instead. For most popular images, this will be UTC. Many base images, particularly minimal ones, won’t even include the tzdata package. You’ll have no /etc/timezone or /etc/localtime files.

    Adding Timezones to Your Containers

    The first part of setting the proper timezone is to make sure tzdata is installed. If your image doesn’t include it, you’ll need to manually add the package as part of your Dockerfile.

    FROM ubuntu:latest
    ENV DEBIAN_FRONTEND=noninteractive
    RUN apt-get update && apt-get install -y tzdata

    When tzdata installs, you usually get an interactive prompt that lets you select the correct timezone from a menu. This is unhelpful when you’re programmatically building Docker containers. Setting the DEBIAN_FRONTEND environment variable suppresses the prompt and defaults the timezone to UTC.

    Once you’ve got tzdata into your image, you’re ready to configure the correct timezone for your application. The simplest approach is to set the TZ environment variable to the timezone you want to use:

    FROM ubuntu:latest
    ENV TZ=Europe/London
    ENV DEBIAN_FRONTEND=noninteractive
    RUN apt-get update && apt-get install -y tzdata

    If you prefer, you can set the TZ variable when you start containers. Pass it as an environment variable to docker run. This lets you override an image’s default timezone, provided it includes the tzdata package.

    docker run -e TZ=Europe/London -it ubuntu:latest

    An alternative to environment variables is the /etc/timezone file. You can write the required timezone as part of your Dockerfile. If you use this method, you must reconfigure tzdata using your package manager. Remember to use non-interactive mode or you’ll receive the graphical timezone prompt again.

    FROM ubuntu:latest
    RUN echo "Europe/London" > /etc/timezone
    RUN dpkg-reconfigure -f noninteractive tzdata

    Other Techniques

    If you want to guarantee timezone synchronization with the host, you can mount your local tzdata files into your containers. You’ll still need tzdata inside the container for this to work correctly.

    docker run -v /etc/timezone:/etc/timezone -v /etc/localtime:/etc/localtime -it ubuntu:latest

    Although Docker doesn’t provide any built-in support for timezones, that’s not true of all container engines. Podman has a dedicated --tz flag which lets you set the timezone when creating a new container:

    podman run --tz=Europe/London -it ubuntu:latest

    Behind the scenes, Podman will mount an appropriate /etc/localtime file for you. The specified timezone will persist for the lifetime of the container.

    Podman also lets you set a default timezone for containers created without the --tz flag. Create or edit .config/containers/containers.conf in your home directory. Add a tz setting on a new line in the file:

    # Used when no --tz flag is given
    tz = "Europe/London"

    Podman’s native timezone integration makes it easier to work with than Docker. As Podman’s CLI is compatible with Docker’s, making the switch can be worth considering if you’re frequently working with containers in different timezones.

    Summary

    Timezones are often overlooked when setting up Docker containers. Most base images default to UTC time which can lead to confusion when the host’s timezone is different.

    By installing the tzdata package, your container gains compatibility with all timezones via the TZ environment variable, /etc/timezone, and /etc/localtime. Alternatively, you can sync your host’s timezone by mounting the relevant files into your containers.

    Finally, remember that these considerations also apply to hosted Docker services and Kubernetes clusters. Your containers will use UTC time unless instructed otherwise. As long as you can set environment variables, you’ll be able to use TZ to adjust the timezone for your workloads.



    Source link

    Previous articleBitcoin price – live: Police steamroll thousands of crypto mining rigs as miners flee China
    Next articleHow to connect AirPods to Apple TV